Есть ли в SQL конструкция, которая позволила бы мне сделать что-то вроде следующего:
Да, почти так, как вы это написали. Просто заключите col1, col2
в скобки:
-- 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), ...) ;
Однако, если вы попробуете это в СУБД, вы можете обнаружить, что это не работает. Потому что не все СУБД реализовали все функции (развивающегося) стандарта SQL. Это работает в последних версиях Oracle, MySQL, Postgres, DB2 и HSQLDB (это не было хорошо оптимизировано в MySQL и не использовало индексы, поэтому его следует избегать, если они не исправили это в 5.7).
См. Документацию MySQL об IN
операторах и документацию Postgres о конструкторах Row . Два * (или более) значения в скобках называются конструктором строк .
Другие способы, которые выражают ту же идею:
-- 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) ;
Оба работают в Postgres и DB2 (afaik). Последний также можно изменить для работы в 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 ;
Его также можно изменить, чтобы он работал везде, сначала поместив значения в (временную или постоянную) таблицу:
-- 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 ;
И всегда есть длинный путь или преобразование в IN
длинное выражение, OR
которое должно работать везде:
-- works in all SQL DBMS
SELECT whatever
FROM t
WHERE col1 = val1a AND col2 = val2a
OR col1 = val1b AND col2 = val2b
---
;
*: Фактически это может быть только одно значение ROW(v)
, см. Документацию Postgres.
WHERE (x, y) IN (a,b)
? Я использую MySql. Возможно, я не знаю, как называется эта конструкция.IN
и Postgres: конструкторыWHERE EXISTS (SELECT t.col1, t.col2 [FROM DUAL] INTERSECT VALUES(val1, val2), (…, …), …)
.источник
'a-b', 'c'
и'a', 'b-c'
. И это с треском провалится для любого типа, который не может быть преобразован вvarchar(max)
.