如何轻松查看SQL中是否有多个表互斥?

时间:2018-06-07 08:36:05

标签: sql sql-server

我有1个主表,其中包含我的整个id组和15个不同的表,这些表是这个主表的子集(但不是集体详尽的,即主表中的id不在15个不同的表中的任何一个中) 。我正在寻找一种聪明的方法来查看15个表中是否有任何具有相同ID的表,如果是,则为每对表相交的ID的名称和数量。我认为这可以通过为每个表使用14个内部联接来完成。但是,可能有一种我无法想到的更聪明的方式。对于我能做什么的任何想法?

也许它可能是一个矩阵,显示每对表的交集。也许是这样的:

+----------+--------+--------+--------+----------+---------+
|          | Table1 | Table2 | Table3 | Table... | Table15 |
+----------+--------+--------+--------+----------+---------+
| Table1   |      0 |      5 |      2 |      ... |       0 |
| Table2   |      5 |      0 |     12 |      ... |       9 |
| Table3   |      2 |     12 |      0 |      ... |       6 |
| Table... |    ... |    ... |    ... |      ... |      ...|
| Table15  |      0 |      9 |      6 |      ... |       0 |
+----------+--------+--------+--------+----------+---------+

2 个答案:

答案 0 :(得分:2)

我会做一些事情(我不确定MSSQL语法):

with grand_table as (
select 't1' as "table_id", id from table1
UNION ALL
select 't2', id from table2
UNION ALL 
...
select 't15', id from table15 )

SELECT t1.table_id, t2.table_id, count(*) 
from grand_table t1 full outer join grand_table t2 on t1.id=t2.id
group by t1.table_id, t2.table_id

我认为这与加入表的所有组合基本相同,但它看起来更整洁。 它可能效率极低,但是再一次,你需要所有的组合才能得到你的结果。

答案 1 :(得分:1)

Yossi走在正确的轨道上,但查询并不能完全构建0。切换到inner join会获得所有非零值。您可以稍微改变零值:

with grand_table as (
      select distinct 't1' as table_name, id from table1
      union all
      select distinct 't2', id from table2
      union all 
      ...
      select 't15', id from table15
    ),
    tables as (
     select v.*
     from (values ('t1'), ('t2'), . . . ('t15')) v(table_name)
    )
select t1.table_name, t2.table_name, count(gt2.id) as num_in_common
from tables t1 cross join
     tables t2 left join
     grand_table gt1
     on gt1.table_name = t1.table_name left join
     grand_table gt2
     on gt2.table_name = t2.table_name and
        gt2.id = t2.id
group by t1.table_name, t2.table_name;

请注意使用select distinctunion all之前减少数据。这对计数和表现很重要。

但是,更有效的方法可能是一次性显示所有表之间的重叠:

with grand_table as (
      select distinct id, 1 as t1, 0 as t2, . . . 0 as t15
      union all
      select distinct id, 0, 1, . . . 0
      union all 
      ...
      select id, 0, 0, . . . 1
    )
select t1, t2, . . . t15, count(*), min(id), max(id)
from (select id, sum(t1) as t1, sum(t2) as t2, . . . , sum(t15) as t15
      from grand_table
      group by id
     ) x
group by t1, t2, . . . t15;

这是我在查找表间重叠时通常采用的方法。