2

我有一份报告需要每个案例的前 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),如果添加了值,则将“无”作为值。如果我不知道提前丢失了哪些行,那么添加缺失行的最佳方法是什么?

这是我的查询:

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)
4

5 回答 5

4

我会使用递归 CTE 来自动生成 1-18 的编号列表,然后离开该列表。然后使用 CASE 语句调整 Value 字段。

;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
于 2013-10-09T16:43:58.873 回答
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
于 2013-10-09T16:37:08.530 回答
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

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

于 2013-10-09T16:48:56.150 回答
1

TL;DR SQL 小提琴

像所有行业的乔恩一样,我也喜欢使用序列(或数字)表。

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
于 2013-10-25T21:05:23.573 回答
0

This is the solution that I used. I used some of @Jon of All Trades and @huMpty duMpty code.

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
于 2013-10-09T21:04:53.863 回答