存在于多个表中的值

时间:2015-08-17 11:34:45

标签: sql postgresql

我有3张桌子。所有这些都有一个列id。我想找出表中是否有任何共同的值。假设表名为a.b和c,如果存在id值3是a和b,则存在问题。查询可以/应该在第一次出现时退出。没有必要进一步探讨。我现在拥有的是像

( select id from a intersect select id from b ) 
union 
( select id from b intersect select id from c ) 
union
( select id from a intersect select id from c ) 

显然,这不是很有效率。数据库是PostgreSQL,版本9.0

id在各个表中不唯一。可以在同一个表中包含重复项。但是如果3个表中只有2个表中存在一个值,那么还需要对其进行标记,并且不需要在第三个表中检查是否存在,或者检查是否有更多这样的值。一个值,存在于多个表中,我可以停止。

4 个答案:

答案 0 :(得分:1)

虽然id在任何给定的表中都不是唯一的,但它应该是唯一的表; union distinct id应该是唯一的,所以:

select id from (
  select distinct id from a
  union all
  select distinct id from b
  union all
  select distinct id from c) x
group by id
having count(*) > 1

请注意union all的使用,它会保留重复项(普通union会删除重复项)。

答案 1 :(得分:0)

我建议一个简单的join

select a.id
from a join
     b
     on a.id = b.id join
     c
     on a.id = c.id
limit 1;

如果您的查询使用uniongroup by(或order by,但此处不相关),那么您需要处理所有返回单行之前的数据。只要找到第一个值,join就可以开始返回行。

另一种类似的方法是:

select a.id
from a
where exists (select 1 from b where a.id = b.id) and
      exists (select 1 from c where a.id = c.id);

如果a是最小的表格而idbc中的索引,那么这可能会非常快。

答案 2 :(得分:0)

试试这个

set()

答案 3 :(得分:0)

  • 可以在同一张表中复制。
  • 查询可以/应该在第一次出现时退出。
SELECT 'OMG!' AS  danger_bill_robinson
WHERE EXISTS (SELECT 1
        FROM  a,b,c -- maybe there is a place for old-style joins ...
        WHERE a.id = b.id
        OR a.id = c.id
        OR c.id = b.id
        );

更新:看起来优化者不喜欢具有3 OR条件的carthesian连接。以下查询有点快:

SELECT 'WTF!' AS danger_bill_robinson
WHERE exists (select 1 from a JOIN b USING (id))
  OR exists (select 1 from a JOIN c USING (id))
  OR exists (select 1 from c JOIN b USING (id))
    ;