使用EXISTS
而不是IN
: exists 更清晰(恕我直言),并且在大多数情况下它也更快。(IN (...)
需要删除/抑制重复项和 NULL,因此:对集合进行排序)
在这种特殊情况下:聚合子查询只需要找出 group count() > 1
。查询优化器可能没有意识到这一点,并在将它们与1
.
SELECT tt.id
FROM thetable tt
WHERE EXISTS (
SELECT * FROM thetable ex
WHERE ex.column1 = tt.column1 AND ex.id <> tt.id
);
WRT 对 NULL 的抑制:如果其中一个或(或两者)碰巧为 NULL,则该WHERE ex.column1 = tt.column1
子句将始终产生 false 。ex.column1
tt.column1
更新。看来 OP 也想要带有 的元组column1 IS NULL
,如果有更多的话。简单的解决方案是使用哨兵值(在 中不存在的值columnn1
)并将其用作代理:(在下面的片段中-1
用作代理值)
SELECT tt.id
FROM thetable tt
WHERE EXISTS (
SELECT * FROM thetable ex
WHERE COALESCE(ex.column1, -1) = COALESCE(tt.column1, -1)
AND ex.id <> tt.id
);
另一种(显而易见的)方法是显式检查 NULL,但这需要一个OR
子句和一堆括号,例如:
SELECT tt.id
FROM thetable tt
WHERE EXISTS (
SELECT * FROM thetable ex
WHERE (ex.column1 = tt.column1
OR (ex.column1 IS NULL AND tt.column1 IS NULL)
)
AND ex.id <> tt.id
);