WHERE col1,col2 IN(...)[使用复合主键的SQL子查询]

Phr*_*ogz 36 sql subquery composite-primary-key

给定foo具有复合主键的表(a,b),是否存在用于编写查询的合法语法,例如:

SELECT ... FROM foo WHERE a,b IN (SELECT ...many tuples of a/b values...);
UPDATE foo SET ... WHERE a,b IN (SELECT ...many tuples of a/b values...);
Run Code Online (Sandbox Code Playgroud)

如果这是不可能的,并且您无法修改架构,那么如何执行上述等效操作?

我还将在这里为这些别名的搜索命中设置术语"复合主键","子选择","子选择"和"子查询".

编辑:我对标准SQL的答案感兴趣,以及那些适用于PostgreSQL和SQLite 3的答案.

Dou*_*rie 26

sqlite> create table foo (a,b,c);
sqlite> create table bar (x,y);
sqlite> select * from foo where exists (select 1 from bar where foo.a = bar.x and foo.b = bar.y);
Run Code Online (Sandbox Code Playgroud)

替换select 1 from bar你的select ... many tuples of a/b values ....

或者创建一个临时表,select ... many tuples of a/b values ...并使用它来代替bar..


one*_*hen 19

您的语法非常接近标准SQL!

以下是有效的FULL SQL-92(由Mimer SQL-92 Validator确认)

SELECT * 
  FROM foo 
  WHERE (a, b) IN (
                   SELECT a, b 
                      FROM bar
                  );
Run Code Online (Sandbox Code Playgroud)

当然,并非每个SQL产品都支持完整的SQL-92(羞耻!)如果有人想在Microsoft SQL Server中看到这种语法,他们可以在这里投票.

更广泛支持的另一个SQL-92构造(例如,由Microsoft SQL Server和Oracle)是INTERSECT例如

SELECT a, b
  FROM Foo
INTERSECT
SELECT a, b
  FROM Bar;
Run Code Online (Sandbox Code Playgroud)

请注意,这些构造正确处理了NULL值,这与其他一些建议不同,例如那些使用EXISTS (<equality predicates>),连接值等的建议.

  • PostgreSql支持此功能.`SELECT*FROM foo WHERE(a,b)IN((1,2),(3,4))` (2认同)
  • 仅供参考,“ INTERSECT”的对面是“ EXCEPT” (2认同)

Ost*_*tin 9

你犯了一个很小的错误.你必须在括号中加上a,b.

SELECT ... FROM foo WHERE (a,b) IN (SELECT f,d FROM ...);
Run Code Online (Sandbox Code Playgroud)

这样可行!