T-SQL加入NULL和NOT NULL记录

时间:2016-11-30 22:20:43

标签: sql sql-server sql-server-2016

代码:

CREATE TABLE [dbo].[T1] ( [ID1] INT NOT NULL, [ID2] INT NOT NULL );
CREATE TABLE [dbo].[T2] ( [ID1] INT NOT NULL, [ID2] INT NULL, [VAL] INT NOT NULL );

INSERT INTO [dbo].[T1] ( [ID1], [ID2] )
VALUES  ( 1, 1 )
        ,( 1, 2 )
        ,( 1, 3 )
        ,( 1, 4 )
        ,( 1, 5 )
        ,( 2, 1 );

INSERT  INTO [dbo].[T2] ( [ID1], [ID2], [VAL] )
VALUES  ( 1, NULL, 25000 )
        ,( 1, 2, 30000 )
        ,( 2, NULL, 30000 );

目标:

T1有一个完整的ID1和ID2映射列表 T2是一个外表,其中一些ID1 / ID2映射到Val。

当T2.ID2 = NULL时,最终目标是“交叉连接”T1和T2(ID1 / ID2)但是当T2.ID2具有NOT NULL值并且保持VAL不从T2时跳过该T1.ID2的输出对于NOT-NULL T2.ID2s。表现必须快!!!!

期望的输出:

ID1 ID2 VAL
1   1   25000
1   2   30000 -- T1.ID2 = 2 takes the priority 
1   3   25000
1   4   25000
1   5   25000
2   1   30000

我的尝试:

SELECT  [T2].[ID1]
      , [T1].[ID2]
      , [T2].[VAL]
FROM    [dbo].[T1] [T1]
JOIN    [dbo].[T2] [T2]
ON      [T1].[ID1] = [T2].[ID1]
WHERE   [T2].[ID2] IS NULL
        OR [T1].[ID2] IN (SELECT    [T3].[ID2]
                          FROM      [dbo].[T2] [T3]
                          WHERE     [T2].[ID1] = [T3].[ID1] 
                                    AND [T2].[ID2] = [T3].[ID2] )
--ORDER BY  [T2].[ID1]
--        , [T1].[ID2]
--        , [T2].[VAL];

当前输出:

ID1 ID2 VAL
1   1   25000
1   2   25000
1   3   25000
1   4   25000
1   5   25000
1   2   30000
2   1   30000

DROP TABLE [dbo].[T1];
DROP TABLE [dbo].[T2];

1 个答案:

答案 0 :(得分:2)

您的查找表中有一个默认值。您可以使用left joincoalesce()

来解决此问题
select t1.id1, t1.id2,
       coalesce(t2.val, t2default.val) as val
from t1 left join
     t2
     on t1.id1 = t2.id1 and t1.id2 = t2.id2 left join
     t2 t2default
     on t1.id1 = t2default.id1 and t2default.id2 is null;

假设在连接中使用的id列上有正确的索引,性能应该非常好。

如果您关心性能,可能值得尝试另一种方法:

select t1.id1, t1.id2, t2.val
from t1 outer apply
     (select top 1 t2.*
      from t2
      where t2.id1 = t1.id and (t2.id2 is null or t2.id2 = t1.id2)
      order by (case when t2.id2 = t1.id2 then 1 else 2 end)
     ) t2;

这对我来说似乎更复杂,但有时apply具有令人惊讶的良好性能特征。