TSQL - 填写缺失的记录

时间:2018-04-04 22:10:44

标签: sql sql-server tsql sql-server-2012

代码:

CREATE TABLE #Temp
    (
        [ID1] INT
      , [ID2] INT
      , [ID3] INT
      , [Val] BIT
      , PRIMARY KEY CLUSTERED ( [ID1], [ID2], [ID3] )
    ) ;
INSERT INTO #Temp
SELECT  1
      , 10
      , 100
      , 1
UNION ALL
SELECT  1
      , 10
      , 101
      , 1
UNION ALL
SELECT  1
      , 11
      , 100
      , 1
UNION ALL
SELECT  1
      , 11
      , 101
      , 1
UNION ALL
SELECT  2
      , 10
      , 100
      , 1 ;

CREATE TABLE #Temp_ID3
    (
        [ID3] INT
    ) ;
INSERT INTO #Temp_ID3
SELECT  100
UNION ALL
SELECT  101
UNION ALL
SELECT  102 ;

SELECT  [ID1]
      , [ID2]
      , [ID3]
      , [Val]
FROM    #Temp ;

SELECT  [ID3]
FROM    #Temp_ID3 ;

DROP TABLE #Temp_ID3 ;
DROP TABLE #Temp ;

输出:

ID1 ID2 ID3 Val
1   10  100 1
1   10  101 1
1   11  100 1
1   11  101 1
2   10  100 1

目标: 在#Temp表(现有ID1 / ID2组合的ID1 / ID2 / ID3组合)中查找缺少的ID3记录 - 来自#Temp_ID3表。对于那些丢失的记录,Val应该是假的。期望的输出是有意义的。

我可以从#Temp获得不同的ID1 / ID2,与ID3交叉连接并创建数据集。将#Temp连接到这个新数据集,并以这种方式插入记录,但寻找更“简单”的方式。

这是“复杂”的方式。

;WITH CTE AS
    (
        SELECT      DISTINCT
                    [TT].[ID1]
                  , [TT].[ID2]
                  , [T3].[ID3]
        FROM        #Temp_ID3 AS [T3]
        CROSS JOIN  (
                        SELECT  DISTINCT
                                [ID1]
                              , [ID2]
                        FROM    #Temp
                    ) AS [TT]
    )
SELECT      [C].[ID1]
          , [C].[ID2]
          , [C].[ID3]
          , COALESCE ( [TT].[Val], 0 ) AS [Val]
FROM        CTE     AS [C]
LEFT JOIN   #Temp   AS [TT]
ON          [C].[ID1]     = [TT].[ID1]
            AND [C].[ID2] = [TT].[ID2]
            AND [C].[ID3] = [TT].[ID3]
ORDER BY    [C].[ID1]
          , [C].[ID2]
          , [C].[ID3] ;

期望的输出:

ID1 ID2 ID3 Val
1   10  100 1
1   10  101 1
1   10  102 0       -- Filling Missing ID3 Record w/ default Val = 0
1   11  100 1
1   11  101 1
1   11  102 0       -- Filling Missing ID3 Record w/ default Val = 0
2   10  100 1
2   10  101 0       -- Filling Missing ID3 Record w/ default Val = 0
2   10  102 0       -- Filling Missing ID3 Record w/ default Val = 0

2 个答案:

答案 0 :(得分:1)

使用@Echo Off Set "name=SomeName" Set "variable=Value" Rem Write to Compile.bat Echo Press any key to write to Compile.bat Pause > Nul ( Echo @Echo Off Echo %%variable%% = %variable% Echo Pause ) > "%name%\Compile.bat" Echo Finished writing to Compile.bat Timeout 3 /NoBreak > Nul Rem Rest of code below here 生成行,然后使用cross join填写值:

left join

如果其中一个表实际拥有子标识,则不必使用子查询来生成id。

编辑:

对于评论中的修订版,您可以做一些非常相似的事情:

select t1.id1, t2.id2, t3.id3, coalesce(t.val, 0) as val
from (select distinct id1 from #temp) t1 cross join
     (select distinct id2 from #temp) t2 cross join
     (select distinct id3 from #temp) t3 left join
     #temp t
     on t.id1 = t1.id1 and t.id2 = t2.id2 and t.id3 = t3.id3;

答案 1 :(得分:1)

根据示例,您只需cross join self join

select distinct t.id1, t.id2, t3.id3, coalesce(t1.val, 0) as Val 
from #Temp t cross join #Temp_ID3 t3
left join #temp t1 
          on t1.id1 = t.id1 and t1.id2 = t.id2 and t1.id3 = t3.id3;