Y at-il une construction en SQL qui me permettrait de faire quelque chose comme ce qui suit:
Oui, presque, exactement comme vous l'avez écrit. Il suffit de mettre col1, col2
entre parenthèses:
-- 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), ...) ;
Si vous l’essayez cependant dans un SGBD, vous constaterez peut-être que cela ne fonctionne pas. Parce que tous les SGBD n’ont pas implémenté toutes les fonctionnalités du standard SQL (évolutif). Cela fonctionne dans les dernières versions d'Oracle, MySQL, Postgres, DB2 et HSQLDB (il n'était pas bien optimisé dans MySQL et n'utilisait pas d'index, il devrait donc être évité là-bas, à moins que cela ne soit corrigé dans la version 5.7).
Voir la documentation MySQL sur les IN
opérateurs et la documentation Postgres sur les constructeurs de lignes . Les deux * (ou plus) valeurs entre parenthèses sont appelées constructeurs de lignes .
Autres moyens qui expriment la même idée:
-- 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) ;
Les deux travaillent dans Postgres et DB2 (autant que je sache). Le dernier peut également être modifié pour fonctionner dans 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 ;
Il peut également être modifié pour fonctionner partout, en plaçant d'abord les valeurs dans une table (temporaire ou permanente):
-- 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 ;
Et il y a toujours le long chemin à parcourir ou convertir le IN
à une expression longue avec OR
qui devrait fonctionner partout:
-- works in all SQL DBMS
SELECT whatever
FROM t
WHERE col1 = val1a AND col2 = val2a
OR col1 = val1b AND col2 = val2b
---
;
*: En réalité, il ne peut s'agir que d'une seule valeur, avec ROW(v)
, voir la documentation Postgres.
WHERE (x, y) IN (a,b)
? J'utilise MySql. Peut-être que je ne sais pas comment s'appelle cette construction.IN
et Postgres: Constructeurs de lignesWHERE EXISTS (SELECT t.col1, t.col2 [FROM DUAL] INTERSECT VALUES(val1, val2), (…, …), …)
.la source
'a-b', 'c'
et'a', 'b-c'
. Et cela échouera misérablement pour tous les types qui ne peuvent pas être convertisvarchar(max)
.