这样的事情是可能的(我知道这个说法不起作用,我试过了):
SELECT * FROM t WHERE t.x OR t.y IN (SELECT id FROM z)
实施例
表t:
|id|x |y
|1 |101|201
|2 |102|202
表z:
|id |
|101 |
|201 |
从这张表中我想选择属性x或属性y包含在表z的id列表中的所有条目。
我知道我能做到
SELECT * FROM t WHERE t.x IN (SELECT id FROM z) OR t.y IN (SELECT id FROM z)
但是当IN
值来自复杂的子查询(在IN
子句中都是相同的)时,这感觉非常低效。
或者当前的查询规划器实现是否足够聪明,以确定两个子查询都给出相同的结果并且只执行一次?或者可能还有另一个使用EXISTS
的解决方案,我目前看不到?
PS:我使用Postgres,但我正在寻找通用的解决方案。
答案 0 :(得分:4)
使用EXISTS
SELECT * FROM t WHERE exists (SELECT 1 FROM z where z.id in (t.x,t.y))
答案 1 :(得分:1)
如果z
是一个复杂的查询,那么您可以使用CTE来简化代码:
WITH z AS (
. . .
)
SELECT *
FROM t
WHERE t.x IN (SELECT id FROM z) OR t.y IN (SELECT id FROM z);
您也可以使用JOIN
或EXISTS
代替:
SELECT *
FROM t
WHERE EXISTS (SELECT 1
FROM z
WHERE z.id IN (t.x, t.y)
);
JOIN
版本的缺点是,由于z
中的重复行,行可以成倍增加。
也就是说,具有两个IN
表达式的版本可能效率最高。
答案 2 :(得分:0)
...试
SELECT t.* FROM t join z on t.x = z.id or t.y = z.id