SQL - 如何查询以查找两个colouch是否为1to1 1tomany manytomany关系?

时间:2017-12-05 19:14:00

标签: sql sql-server relationship

我想绘制一个类图来描述columes之间的关系。如何查询两个collast是1to1还是1tomany或manytomany关系?例如,下表显示了列" name"与colume" prod"是1对多。

enter image description here

3 个答案:

答案 0 :(得分:0)

任何返回的记录都意味着1对多

select A
from table
group by A,B
having count(*) >1

答案 1 :(得分:0)

我发现下面的查询工作。它会显示第一列(iename)中第二列(ieprod)中有多个值的任何记录,反之亦然,它们可以显示两列是1:1还是1:多或多: 1或多:很多

    select name, count(prod) 
from (select name, prod from test.relationship
      group by name, prod) subtable
group by name
having count(prod) > 1

答案 2 :(得分:0)

困难的部分是检测与电路类似的多对多关系。对于任何列对,您需要找到任何一侧的值是否有另一个配对。对于1-many或many-1来说,它更直接,只需在外部apply()中按行匹配。这看起来有点令人生畏,但似乎有把戏......

    create table #relationships (col_a char(1), col_b int)

-- one to one
insert into #relationships select 'a', 1

-- one to many
insert into #relationships select 'b', 2
insert into #relationships select 'b', 3

-- many to many
insert into #relationships select 'c', 4
insert into #relationships select 'c', 5
insert into #relationships select 'd', 5

-- many to one
insert into #relationships select 'e', 6
insert into #relationships select 'f', 6


select  a.col_a,
        a.col_b,
        case when circuit.col_a is not null then 'Many-Many' -- order important 
             when cnt1.cnt1 = 1 and cnt2.cnt2 = 1 then 'One-One'
             when cnt1.cnt1 = 2 and cnt2.cnt2 = 1 then 'One-Many'
             when cnt1.cnt1 = 1 and cnt2.cnt2 = 2 then 'Many-One'
        end
from #relationships a
cross apply( select count(*) cnt1
             from ( select distinct col_b
                    from #relationships b
                    where b.col_a = a.col_a )x) cnt1
cross apply( select count(*) cnt2
             from ( select distinct col_a
                    from #relationships b
                    where b.col_b = a.col_b )x) cnt2

left join ( select x.col_a,
                   x.col_b 
            from #relationships a
            outer  apply ( select b.col_a,
                                  b.col_b
                           from #relationships b
                            where  a.col_a = b.col_a
                                    and exists ( select 1
                                                 from #relationships c
                                                 where b.col_b = c.col_b
                                                   and c.col_a <> a.col_a ) 
                              and ( a.col_b = b.col_b
                                    and exists ( select 1
                                                 from #relationships c
                                                 where b.col_a = c.col_a
                                                   and c.col_b <> a.col_b ))) x 
        ) circuit
    on a.col_a = circuit.col_a 
    or  a.col_b = circuit.col_b 

col_a col_b       
----- ----------- ---------
a     1           One-One
b     2           One-Many
b     3           One-Many
c     4           Many-Many
c     5           Many-Many
d     5           Many-Many
e     6           Many-One
f     6           Many-One