Existe uma construção no SQL que me permita fazer algo como o seguinte:
Sim, existe quase exatamente como você o escreveu. Basta colocar col1, col2
parênteses:
-- works in PostgreSQL, Oracle, MySQL, DB2, HSQLDB
SELECT whatever
FROM t --- you missed the FROM
WHERE (col1, col2) --- parentheses here
IN ((val1a, val2a), (val1b, val2b), ...) ;
Se você tentar no entanto em um DBMS, poderá achar que ele não funciona. Porque nem todos os DBMS implementaram todos os recursos do padrão SQL (em evolução). Isso funciona nas versões mais recentes do Oracle, MySQL, Postgres, DB2 e HSQLDB (não foi bem otimizado no MySQL e não utiliza índices, portanto, deve ser evitado nesse local, a menos que seja corrigido na versão 5.7).
Veja a documentação do MySQL sobre IN
operador e a documentação do Postgres sobre os construtores Row . Os dois valores * (ou mais) entre parênteses são chamados de construtor de linhas .
Outras maneiras que expressam a mesma idéia:
-- works in PostgreSQL, DB2
SELECT whatever
FROM t
WHERE (col1, col2)
IN ( VALUES (val1a, val2a), (val1b, val2b), ...) ;
SELECT t.whatever
FROM t
JOIN
( VALUES (val1a, val2a), (val1b, val2b), ...) AS x (col1, col2)
ON (x.col1, x.col2) = (t.col1, t.col2) ;
Ambos trabalham no Postgres e no DB2 (afaik). O último também pode ser modificado para funcionar no SQL Server:
-- works in PostgreSQL, DB2, SQL Server
SELECT t.whatever
FROM t
JOIN
( VALUES (val1a, val2a), (val1b, val2b), ...) AS x (col1, col2)
ON x.col1 = t.col1
AND x.col2 = t.col2 ;
Também pode ser modificado para funcionar em qualquer lugar, colocando os valores em uma tabela (temporária ou permanente) primeiro:
-- works everywhere
CREATE TABLE values_x
( col1 ...,
col2 ...) ;
-- use appropriate for the DBMS syntax here
INSERT INTO values_x (col1, col2)
VALUES (val1a, val2a), (val1b, val2b), ... ;
SELECT t.whatever
FROM t
JOIN values_x x
ON x.col1 = t.col1
AND x.col2 = t.col2 ;
DROP TABLE values_x ;
E sempre há o caminho longo ou a conversão IN
para uma expressão longa com OR
isso deve funcionar em qualquer lugar:
-- works in all SQL DBMS
SELECT whatever
FROM t
WHERE col1 = val1a AND col2 = val2a
OR col1 = val1b AND col2 = val2b
---
;
*: Na verdade, pode ser apenas um valor, com ROW(v)
, consulte os documentos do Postgres.
WHERE (x, y) IN (a,b)
? Eu estou usando o MySql. Talvez eu não saiba como essa construção é chamada.IN
e Postgres: Fileira ConstrutoresWHERE EXISTS (SELECT t.col1, t.col2 [FROM DUAL] INTERSECT VALUES(val1, val2), (…, …), …)
.fonte
'a-b', 'c'
e'a', 'b-c'
. E falhará miseravelmente em qualquer tipo que não possa ser convertidovarchar(max)
.