我的报告需要每个案例的前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)
答案 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
加入CorpIdCodes
和ReportCaseList_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