I\'m working on a query like this:
SELECT * FROM requests where (id,langid) IN (SELECT nid,langid FROM node)
My questions are
I checked that with PostgreSQL and it works (it is officially supported), but it's your responsibility to make id ↔ nid and langid ↔ langid column types compatible (or use explicit casting).
I think it is pretty standard construct. I have SQL:2003 draft and there is in predicate defined (as well as mentioned exists predicate).
8.4 <in predicate>
Function
Specify a quantified comparison.
Format
<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:
As checked works well under MySQL too (version 5.0.90-log). Here is documentation link.
Standard and portable SQL would be EXISTS.. and is semantically the same IN
SELECT *
FROM requests R
WHERE
EXISTS (SELECT *
FROM node n
WHERE r.id = n.nid AND r.langid = n.langid
)
The multi-column IN isn't portable to SQL Server or Sybase at least.
Other notes:
Your SQL code is valid as regards the SQL-92 Standard. You can confirm this for yourself using the Mimer SQL-92 online validator (SQL-99 and SQL:2003 flavours also available). However, because it is a feature of Full SQL-92, it is not as widely implemented as perhaps it should be.
Relationally speaking, the operator in question is a semi-join, for which none of the SQL Standards (and none of the vendors' extensions?) has an explicit syntax.
Your query would work in Postgres. Best I'm aware, not in MySQL.
The portable version for DBs that would support it is:
SELECT * FROM requests where ROW(id,langid) IN (SELECT nid,langid FROM node)
(row
is a reserved keyword since SQL:1999.)
A more portable version will be to use exists()
as suggested in the other answer.