Esiste un costrutto in SQL che mi consentirebbe di fare qualcosa del tipo:
Sì, c'è, quasi esattamente come l'hai scritto. Metti col1, col2
tra parentesi:
-- 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 lo provi comunque in un DBMS, potresti scoprire che non funziona. Perché non tutti i DBMS hanno implementato tutte le funzionalità dello standard SQL (in evoluzione). Funziona con le ultime versioni di Oracle, MySQL, Postgres, DB2 e HSQLDB (non è stato ben ottimizzato in MySQL e non usa gli indici, quindi dovrebbe essere evitato lì a meno che non sia stato risolto in 5.7).
Consulta la documentazione MySQL sulla documentazione IN
dell'operatore e Postgres sui costruttori di righe . I due * (o più) valori tra parentesi sono chiamati costruttori di righe .
Altri modi che esprimono la stessa idea:
-- 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) ;
Entrambi funzionano in Postgres e DB2 (afaik). L'ultimo può essere modificato per funzionare anche in 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 ;
Può anche essere modificato per funzionare ovunque, posizionando prima i valori in una tabella (temporanea o 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 ;
E c'è sempre una lunga strada o la conversione IN
in una lunga espressione OR
che dovrebbe funzionare ovunque:
-- works in all SQL DBMS
SELECT whatever
FROM t
WHERE col1 = val1a AND col2 = val2a
OR col1 = val1b AND col2 = val2b
---
;
*: Può effettivamente essere solo un valore, con ROW(v)
, vedi i documenti di Postgres.
WHERE (x, y) IN (a,b)
? Sto usando MySql. Forse non so come si chiama questo costrutto.