¿Hay una construcción en SQL que me permita hacer algo como lo siguiente:
Sí, la hay, casi exactamente como la escribiste. Solo ponga col1, col2
entre paréntesis:
-- 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), ...) ;
Sin embargo, si lo prueba en un DBMS, es posible que no funcione. Porque no todos los DBMS han implementado todas las características del estándar SQL (en evolución). Esto funciona en las últimas versiones de Oracle, MySQL, Postgres, DB2 y HSQLDB (no estaba bien optimizado en MySQL y no usaba índices, por lo que debería evitarse allí a menos que lo arreglaran en 5.7).
Consulte la documentación de MySQL sobre el IN
operador y la documentación de Postgres sobre los constructores de filas . Los dos valores * (o más) entre paréntesis se llaman constructores de filas .
Otras formas que expresan la misma 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) ;
Ambos funcionan en Postgres y DB2 (afaik). El último también se puede modificar para que funcione en 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 ;
También se puede modificar para que funcione en todas partes, colocando primero los valores en una tabla (temporal 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 ;
Y siempre hay un largo camino o convertirlo IN
en una expresión larga con OR
eso debería funcionar en todas partes:
-- works in all SQL DBMS
SELECT whatever
FROM t
WHERE col1 = val1a AND col2 = val2a
OR col1 = val1b AND col2 = val2b
---
;
*: En realidad puede ser solo un valor, con ROW(v)
, ver documentos de Postgres.
WHERE (x, y) IN (a,b)
? Estoy usando MySql. Quizás no sé cómo se llama esta construcción.IN
y Postgres: Constructores de filasWHERE EXISTS (SELECT t.col1, t.col2 [FROM DUAL] INTERSECT VALUES(val1, val2), (…, …), …)
.fuente
'a-b', 'c'
y'a', 'b-c'
. Y fallará miserablemente para cualquier tipo al que no se pueda convertirvarchar(max)
.