2013-10-09 44 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