什么时候应该使用子联接

时间:2019-07-29 08:34:56

标签: sql sql-server join

检查以下代码:

    declare @A table (Id int, b_Id int)
    declare @B table (Id int, c_Id int)
    declare @C table (Id int)

    insert into @A values(1, 10)
    insert into @A values(2, 11)
    insert into @A values(3, null)

    insert into @B values(10, 100)
    insert into @B values(11, null)
    insert into @B values(12, 101)

    insert into @C values(100)
    insert into @C values(101)
    insert into @C values(102)

查询1)

    Select 
        a.Id, b.Id, c.Id 
    from 
        @A a 
        Left join @B b on a.B_Id = b.Id
        join @C c on b.C_Id = c.Id 

查询2)

    Select 
        a.Id, b.Id, c.Id 
    from 
        @A a 
        Left join @B b on a.B_Id = b.Id
        Left join @C c on b.C_Id = c.Id 

查询3)

    Select 
        a.Id, b.Id, c.Id 
    from 
        @A a 
        Left join @B b
            join @C c on b.C_Id = c.Id  
         on a.B_Id = b.Id

这导致: 第一个查询

1   10  100

第二个查询:

 1  10  100
 2  11  NULL
 3  NULL    NULL

第三个查询:

1   10  100
2   NULL    NULL
3   NULL    NULL

现在,我想知道您何时使用第三个查询,其中b的on语句在查询中c的on语句之后。 以及如何重写这一点以获得相同的结果。

2 个答案:

答案 0 :(得分:0)

您在寻找下面的脚本吗?

SELECT A.a_id,
CASE WHEN (A.b_id IS NOT NULL) AND (A.c_id IS NOT NULL) THEN A.b_id END b_id,
CASE WHEN (A.b_id IS NOT NULL) AND (A.c_id IS NOT NULL) THEN A.c_id END c_id
FROM
(
    SELECT A.Id a_id,B.Id b_id,C.Id c_id 
    FROM @A A
    LEFT JOIN @B B  ON A.b_Id = B.Id
    LEFT JOIN @C C ON B.c_Id = C.Id
)A

答案 1 :(得分:0)

您的第三个查询是非常不标准的:

select a.Id, b.Id, c.Id 
from @A a left join
     @B b join
     @C c
     on b.C_Id = c.Id  
     on a.B_Id = b.Id;

如果使用括号来写,这更有意义:

select a.Id, b.Id, c.Id 
from @A a left join
     (@B b join
      @C c
      on b.C_Id = c.Id 
     ) 
     on a.B_Id = b.Id;

您可以使用right join重写它:

select a.Id, b.Id, c.Id 
from @B b join
     @C c
     on b.C_Id = c.Id right join
     @A a 
     on a.B_Id = b.Id;

不过,实际上,我可能会使用子查询:

select a.Id, bc.b_Id, bc.c_Id 
from @A a left join
     (select b.Id as b_id, c.Id as c_id
      from @B b join
           @C c
           on b.C_Id = c.Id  
     ) bc
     on a.B_Id = bc.b_Id;

我发现这最能抓住逻辑的意图。