SQL如何将表与自身进行比较

时间:2014-02-14 20:23:13

标签: sql

所以我想说我有一张包含这些信息的表

 - Tom   BLDG200
 - Kevin BLDG200  
 - Mary  BLDG340

我想找到共享同一栋楼的所有人。所以我希望它打印出Ton和Kevin。但因为玛丽本身不应该打印。我一直在使用它的方式是使用INNER JOIN将它们加入到建筑物中,但是因为我正在比较一个表与它自己的连接,即使它只有一个人。所以在我的情况下,即使我不想要,它也会打印出玛丽。如果两个或更多人共用同一建筑物,我怎样才能打印出来。

3 个答案:

答案 0 :(得分:1)

以下是解决此查询的有效方法:

select t.*
from table t
where exists (select 1
              from table t2
              where t2.name <> t.name and t2.building = t.building
             ) ;

这将最佳地利用building, name上的索引。

大多数数据库都提供窗口/分析功能,这是另一种有效的方法:

select name, building
from (select t.*, count(*) over (partition by building) as cnt
      from table t
     ) t
where cnt > 1;

答案 1 :(得分:0)

假设您的列名称为personbuilding

SELECT t1.person, t2.person 
  FROM `table` t1 
       JOIN `table` t2 
            ON (    t1.building = t2.building 
                AND t1.person > t2.person
                );

此行AND t1.person > t2.person解决了您与Mary的问题。 有更多人的问题,因为他们会分成两对。但如果这不打扰你,那就行了。

此外,followind会工作(但每个人都会看到结果,所以你会列出他们居住的每一个非孤独的人和建筑物)

SELECT t1.person, t1.building 
  FROM `table` t1 
       JOIN `table` t2 
            ON (    t1.building = t2.building 
                AND t1.person > t2.person
                );

答案 2 :(得分:0)

关系代数101.我添加了更多名称,因此您可以看到需要distinct。在我的示例数据中,只有Jane是单独的,不应该在结果中。

with cte (name, building) as (
values
 ('Tom',  'BLDG200'),
 ('Kevin','BLDG200'),
 ('John', 'BLDG200'), 
 ('Jack', 'BLDG200'),  
 ('Mary', 'BLDG340'),
 ('Terry','BLDG340'),
 ('Jane', 'BLDG341')  
)

select 
  distinct
  a.name, a.building 
from 
  cte a 
  join cte b on (a.name <> b.name and a.building = b.building)

SQLFiddle