给定具有复合主键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...);
如果这是不可能的,并且您无法修改架构,那么如何执行上述等效操作?
我还要在这里添加“复合主键”,“子选择”,“子选择”和“子查询”等术语,以便对这些别名进行搜索命中。 < / p>
编辑:我对标准SQL以及可以与PostgreSQL和SQLite 3一起使用的答案感兴趣。
答案 0 :(得分: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);
将select 1 from bar
替换为select ... many tuples of a/b values ...
。
或者创建select ... many tuples of a/b values ...
的临时表格并使用它代替bar
..
答案 1 :(得分:19)
您的语法非常接近标准SQL!
以下是有效的FULL SQL-92(由Mimer SQL-92 Validator确认)
SELECT *
FROM foo
WHERE (a, b) IN (
SELECT a, b
FROM bar
);
当然,并非每个SQL产品都支持完整的SQL-92(羞耻!)如果有人希望Microsoft SQL Server支持这种语法,他们可以投票支持here。
更广泛支持的另一个SQL-92构造(例如,由Microsoft SQL Server和Oracle)INTERSECT
是SELECT a, b
FROM Foo
INTERSECT
SELECT a, b
FROM Bar;
。
NULL
请注意,这些结构可以正确处理EXISTS (<equality predicates>)
值,这与此处的其他一些建议不同,例如:使用{{1}},连接值等的那些
答案 2 :(得分:9)
你犯了一个很小的错误。 你必须在括号中加上a,b。
SELECT ... FROM foo WHERE (a,b) IN (SELECT f,d FROM ...);
有效!
答案 3 :(得分:4)
您建议的IN语法不是有效的SQL。使用EXISTS的解决方案应该适用于所有合理的SQL RDBMS:
UPDATE foo SET x = y WHERE EXISTS
(SELECT * FROM bar WHERE bar.c1 = foo.c1 AND bar.c2 = foo.c2)
请注意,这通常不是特别有效。
答案 4 :(得分:3)
SELECT ...
FROM foo
INNER JOIN (SELECT ...many tuples of a/b values...) AS results
ON results.a = foo.a
AND results.b = foo.b
那你在找什么?
答案 5 :(得分:2)
通过连接,这适用于PostgreSQL:
SELECT a,b FROM foo WHERE a||b IN (SELECT a||b FROM bar WHERE condition);
UPDATE foo SET x=y WHERE a||b IN (SELECT a||b FROM bar WHERE condition);
答案 6 :(得分:0)
JOINS
和INTERSECTS
可以替代IN
,但它们并不像NOT IN
的替代品那样明显,例如:从{{插入行1}}进入TableA
TableB
,TableB
中两个表中的PK
都是合成的。{/ p>
我目前在SQL Server中使用上面的连接方法,但它不是一个非常优雅的解决方案。
答案 7 :(得分:0)
如果您需要一个不需要表中已存在值的元组的解决方案,您可以连接相关的表值和列表中的项目,然后使用“IN”命令。
在postgres中,这将是这样的:
SELECT * FROM foo WHERE a || '_' || b in ('Hi_there', 'Me_here', 'Test_test');
在SQL中,我想它可能看起来像这样:
SELECT * FROM foo WHERE CONCAT(a, "_", b) in ('Hi_there', 'Me_here', 'Test_test');
答案 8 :(得分:0)
Firebird使用此连接公式:
SELECT a,b FROM foo WHERE a || b IN(SELECT a || b FROM bar WHERE 条件);