"Где IN" с несколькими столбцами, определенными в стандартном SQL?
Я работаю над таким запросом:
SELECT * FROM requests where (id,langid) IN (SELECT nid,langid FROM node)
Мои вопросы:
Это работает в mysql и postgresql?
это что-то поддерживается стандартным SQL?
Я знаю, что это не лучшее решение, и JOIN будет работать, но меня это не интересует.
Ответы
Ответ 1
Стандартный и портативный SQL будет EXISTS.. и семантически совпадает с IN
SELECT *
FROM requests R
WHERE
EXISTS (SELECT *
FROM node n
WHERE r.id = n.nid AND r.langid = n.langid
)
Многостолбцовый IN не переносится на SQL Server или Sybase как минимум.
Другие примечания:
- JOIN может потребовать DISTINCT и не совпадает с IN или EXISTS.
- Последний вариант - это INTERSECT, который менее поддерживается и работает как IN/EXISTS
- IIRC некоторые доисторические версии MySQL (3.x?) не поддерживали корреляцию для EXISTS
Ответ 2
Я проверил это с помощью PostgreSQL, и он работает (официально поддерживается), но это ваша обязанность сделать id ↔ nid и langid ↔ langid типы столбцов совместимы (или используют явное литье).
Я думаю, что это довольно стандартная конструкция. Я SQL: проект 2003 года и существует в предикате (а также упомянутый предикат).
8.4 < в предикате >
Функция
Укажите количественное сравнение.
Формат
<in predicate> ::= <row value predicand> <in predicate part 2>
<in predicate part 2> ::= [ NOT ] IN <in predicate value>
<in predicate value> ::=
<table subquery>
| ... (rest is not important here)
EDIT:
Как проверено хорошо работает также в MySQL (версия 5.0.90-log). Вот ссылка документации.
Ответ 3
Ваш запрос будет работать в Postgres. Лучше всего я знаю, а не в MySQL.
Портативная версия для DB, которая будет ее поддерживать:
SELECT * FROM requests where ROW(id,langid) IN (SELECT nid,langid FROM node)
(row
- зарезервированное ключевое слово, так как SQL:1999.)
Более портативная версия будет использовать exists()
, как предложено в другом ответе.
Ответ 4
Ваш SQL-код действителен в отношении стандарта SQL-92. Вы можете подтвердить это самостоятельно, используя онлайн-валидатор Mimer SQL-92 (SQL -99 и SQL: 2003. Однако, поскольку это функция Full SQL-92, она не так широко реализована, как может быть, она должна быть.
Реляционно говоря, рассматриваемый оператор является semi-join, для которого ни один из SQL-стандартов (и ни один из расширений поставщиков?) имеет явный синтаксис.