2013-10-09 42 views
2

我有一份报告,需要每个案例的前18个身份证号。有些案例只有18行,有些只有少数。下面是输出的一个例子:填写表中缺失的行SQL

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

我需要输出什么已经是创纪录的每18行(ID码1-18),并把“无”的值,如果添加它。如果我不知道哪些是提前缺少的,那么添加缺失行的最佳方法是什么?

这里是我的查询:

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) 
+0

这不是很清楚!你需要'idcode'列1-18吗?我可以看到'idcode'的值在这里重复。那么,什么将决定缺失的价值以及如何呢? –

+0

我需要输出每行代码有一行。例如,案例2缺少ID代码1,2,4 ......我需要添加这些缺少的数字,并将“none”指定为值。 –

+0

所以你需要每个'case'值1-18'idcodes'然后? –

回答

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 @[email protected]+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 [email protected]) 

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


Select * from #temp 
+0

如何使用现有的表格而不是#temp执行此操作。该解决方案假定我不会提前知道的已知值。 –

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 
+0

这创建了我不需要的空案例。应始终有一个案例编号。 –

+0

修改了解决方案。现在就试试。 – Matt

+0

; 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 WHEN cce.CorpIdCodeId为NULL,则 '无' ELSE cce.StringValue END AS值, cte.idcode AS IDCODE FROM CTE LEFT JOIN CaseIdCodeEntry CCE ON cce.CorpIdCodeId = cte.idcode LEFT JOIN CorpIdCodes CID ON cce.CorpIdCodeId = CID .CorpIdCodeId LEFT JOIN PhdRpt.ReportCaseList_542 rcl ON cce.CaseCaseId = rcl.CaseCaseId order by CaseID,idcode –

1

矮胖和马特的解决方案应该工作,但作为一个纯粹的我建议你使用一个数字表,而不是光标或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 

顺便说一句,你确定你需要加入CaseIdCodeEntryCorpIdCodesReportCaseList_542?如果他们在那里过滤数据,那很好,但是因为他们没有对输出做出贡献,所以我不得不怀疑。

+0

是的,我必须用它将两个表连接在一起。 –

+0

我试过这个,但我得到的案件编号为空。 –

+0

这里是我的结果的屏幕截图http://oi39.tinypic.com/28qs35z.jpg –

0

这是我使用的解决方案。我使用了所有交易的@Jon和@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 @[email protected]+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 [email protected]) 

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


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

TL; DR SQL Fiddle

像所有的交易我也赞成使用的序列(或数量)表中的乔恩。

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