填写表SQL中缺少的行

时间:2013-10-09 15:50:19

标签: sql sql-server

我的报告需要每个案例的前18个ID代码。有些案例只有18行,有些只有少量。以下是输出的示例:

Case       idcode          value
 2            3             122
 2            6              52 
 2            15            121
 3            1             111 
 3            3             555
 3            6             322

我需要输出的是每条记录18行(idcodes 1-18)并且如果添加它,则为该值添加“none”。如果我不知道哪些是提前丢失的,那么添加缺失行的最佳方法是什么?

这是我的问题:

SELECT 
    rcl.CaseCaseId as Case, cce.StringValue as Value, cce.CorpIdCodeId as idcode
FROM         
    CaseIdCodeEntry AS cce 
INNER JOIN
    CorpIdCodes AS cid ON cce.CorpIdCodeId = cid.CorpIdCodeId 
INNER JOIN
    PhdRpt.ReportCaseList_542 AS rcl ON cce.CaseCaseId = rcl.CaseCaseId
WHERE
    (cce.CorpIdCodeId < 19)

5 个答案:

答案 0 :(得分:4)

我会使用递归CTE自动生成1-18的编号列表,然后LEFT JOIN。然后使用CASE语句调整“值”字段。

;WITH cte AS
(   SELECT DISTINCT CaseCaseId AS CaseID, 1 AS idcode
    FROM PhdRpt.ReportCaseList_542 UNION ALL
    SELECT CaseID, idcode+1 FROM cte WHERE idcode < 18 )
SELECT  cte.CaseID AS [Case], 
        CASE WHEN cce.CorpIdCodeId IS NULL THEN 'None' ELSE cce.StringValue END AS Value, 
        cte.idcode AS idcode
FROM cte
LEFT JOIN CaseIdCodeEntry cid ON cid.CorpCodeId = cte.idcode
LEFT JOIN CorpIdCodes cid ON cce.CorpIdCodeId = cid.CorpIdCodeId
LEFT JOIN PhdRpt.ReportCaseList_542 rcl ON cce.CaseCaseId = rcl.CaseCaseId

答案 1 :(得分:2)

尝试这看起来很好用

create table #temp(iCase int, idcode int,value int)
Insert into #temp values(2,3,122)
Insert into #temp values(2,6,52)
Insert into #temp values(2,15,121)
Insert into #temp values(3,1,11)
Insert into #temp values(3,3,555)
Insert into #temp values(3,6,322)


create table #Val(Id int)

declare @count int =1

while (@count<=18)
begin
    insert into #Val values(@count)
    set @count=@count+1
end

DECLARE @CaseId INT
DECLARE @DataCursor CURSOR
SET @DataCursor = CURSOR FOR
SELECT distinct iCase
From #temp
OPEN @DataCursor
FETCH NEXT
FROM @DataCursor INTO @CaseId
WHILE @@FETCH_STATUS = 0
BEGIN
    INSERT INTO #temp
    SELECT @CaseId,Id,null
    FROM #Val
    WHERE Id NOT IN (
    SELECT idcode
    FROM #temp
    WHERE iCase=@CaseId )

FETCH NEXT
FROM @DataCursor INTO @CaseId
END
CLOSE @DataCursor
DEALLOCATE @DataCursor


Select * from #temp

答案 2 :(得分:1)

Humpty和Matt的解决方案应该有效,但作为纯粹主义者,我建议使用Numbers表而不是光标或CTE。它更简单(恕我直言),对于大批量它应该明显更快:

SELECT
    X.CaseId, N.Number, X.Value
FROM
    Numbers AS N
    LEFT JOIN
        (
        SELECT
            CICE.CaseCaseId AS CaseId, CICE.StringValue AS Value, CICE.CorpIdCodeId AS IdCode
        FROM
            CaseIdCodeEntry AS CICE
            INNER JOIN CorpIdCodes AS CIC ON CICE.CorpIdCodeId = CIC.CorpIdCodeId
            INNER JOIN PhdRpt.ReportCaseList_542 AS RCL ON CICE.CaseCaseId = RCL.CaseCaseId
        ) AS X ON N.Number = X.IdCode
WHERE
    N.Number BETWEEN 1 AND 18

顺便提一下,您确定需要加入CaseIdCodeEntry加入CorpIdCodesReportCaseList_542吗?如果他们在那里过滤数据,那很好,但由于他们没有对输出做出贡献,我不得不怀疑。

答案 3 :(得分:1)

TL; DR SQL Fiddle

与所有交易的Jon一样,我也赞成使用序列(或数字)表。

CREATE TABLE Seq ( seq_num int) 

您可以使用它来填充原始数据中缺失的行;假设您有一张表T来保存您的数据

CREATE TABLE T ( case_num int
                ,code_id int
                ,value char(4)) 

您可以使用以下查询来获取完整填充的结果

WITH All_Codes AS (
    SELECT DISTINCT case_num, seq_num AS code_id
    FROM T, Seq
)    
SELECT All_Codes.case_num
  ,All_Codes.code_id
  ,CASE WHEN value IS NULL THEN 'none' ELSE value END AS value
FROM All_Codes LEFT JOIN T 
  ON All_Codes.case_num = T.case_num AND All_Codes.code_id = T.code_id

结果是

case_num  code_id  value
2         1        none
2         2        none
2         3        122
2         4        none
2         5        none
2         6        52
2         7        none
2         8        none
2         9        none
2         10       none
2         11       none
2         12       none
2         13       none
2         14       none
2         15       121
2         16       none
2         17       none
2         18       none
3         1        111
3         2        none
3         3        555
3         4        none
3         5        none
3         6        322
3         7        none
3         8        none
3         9        none
3         10       none
3         11       none
3         12       none
3         13       none
3         14       none
3         15       none
3         16       none
3         17       none
3         18       none

答案 4 :(得分:0)

这是我使用的解决方案。我使用了@Jon of All Trades和@huMpty duMpty代码。

SELECT     cice.CaseCaseId, cice.CorpIdCodeId, cice.DateValue, cice.DoubleValue, cice.StringValue, cic.Label
into #TT
FROM         CaseIdCodeEntry AS cice INNER JOIN
                      CorpIdCodes AS cic ON cice.CorpIdCodeId = cic.CorpIdCodeId INNER JOIN
                      PhdRpt.ReportCaseList_542 AS rcl ON cice.CaseCaseId = rcl.CaseCaseId
WHERE     (cice.CorpIdCodeId <= 18)
ORDER BY cice.CaseCaseId, cice.CorpIdCodeId


create table #Val(Id int)

declare @count int =1

while (@count<=18)
begin
    insert into #Val values(@count)
    set @count=@count+1
end

DECLARE @CaseId INT
DECLARE @DataCursor CURSOR
SET @DataCursor = CURSOR FOR
SELECT distinct CaseCaseId
From #TT
OPEN @DataCursor
FETCH NEXT
FROM @DataCursor INTO @CaseId
WHILE @@FETCH_STATUS = 0
BEGIN
    INSERT INTO #TT
    SELECT @CaseId,Id,null, null, null, 'none'
    FROM #Val
    WHERE Id NOT IN (
    SELECT CorpIdCodeId
    FROM #TT
    WHERE CaseCaseId=@CaseId )

FETCH NEXT
FROM @DataCursor INTO @CaseId
END
CLOSE @DataCursor
DEALLOCATE @DataCursor


Select * from #TT
order by CaseCaseId, CorpIdCodeId
drop table #TT, #Val