Is “Where IN” with multiple columns defined in Standard SQL?

前端 未结 4 1474
名媛妹妹
名媛妹妹 2020-12-17 16:33

I\'m working on a query like this:

SELECT * FROM requests where (id,langid) IN (SELECT nid,langid FROM node)

My questions are

  • does this
  • 相关标签:
    4条回答
    • 2020-12-17 17:13

      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.

      0 讨论(0)
    • 2020-12-17 17:17

      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:

      • A JOIN may require a DISTINCT and is not the same as IN or EXISTS.
      • The final option is INTERSECT which is less commonly supported and works like IN/EXISTS
      • IIRC some prehistoric MySQL versions (3.x?) didn't support the correlation for EXISTS
      0 讨论(0)
    • 2020-12-17 17:23

      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.

      0 讨论(0)
    • 2020-12-17 17:27

      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.

      0 讨论(0)
    提交回复
    热议问题