我正在查询表格以获取一些基本信息,文件编号,案例类型,状态等。此外,我需要为138个案例状态类型中的每一个显示一个列,该列将显示案例具有该状态的日期。这是一个示例:
SELECT FileNum,
CaseType,
CurrentCaseStatus,
(SELECT TOP 1 EventDt FROM caseStatusHistory WHERE CaseID = c.caseID AND CaseStatus = 'CS001' ORDER BY EventDt DESC) AS [Charge - Phone],
(SELECT TOP 1 EventDt FROM caseStatusHistory WHERE CaseID = c.caseID AND CaseStatus = 'CS002' ORDER BY EventDt DESC) AS [Charge - Written],
-- 136 more just like the live above
FROM Case c
我可以在另一个表中查询所有案例状态类型:
SELECT Code, Description
FROM caseStatus
WHERE Code BETWEEN 'CS001' AND 'CS138'
ORDER BY Code
如何动态创建每个列而不必手动编写138个选择语句?
答案 0 :(得分:0)
这将非常缓慢 - 138个相关的子查询。我认为您可以使用OUTER JOIN
和GROUP BY
与MAX和CASE
获得相同的结果:
Select c.filenum,
c.casetype,
c.currentcasestatus,
max(case when csh.CaseStatus = 'CS001' then EventDt end) as [Charge - Phone],
max(case when csh.CaseStatus = 'CS002' then EventDt end) as [Charge - Written]
from case c
left join casestatushistory csh on c.caseid = csh.caseid
group by c.filenum,
c.casetype,
c.currentcasestatus
顺便说一句,我建议只写出声明 - 它不会花那么长时间,它会执行动态的SQL方法。除非Phone
和Written
在另一列中,否则我不完全确定如何使用动态sql获取列名。
答案 1 :(得分:0)
尝试使用PIVOT。下面的SQL应该可以工作 -
--Select the pivot data into a temp table
SELECT c.caseID,
c.FileNum,
c.CaseType,
c.CurrentCaseStatus,
csh.EventDt,
cs.Description
INTO #StatusDates
FROM [Case] c
LEFT JOIN caseStatusHistory csh
ON csh.caseID = c.caseID
LEFT JOIN caseStatus cs
ON cs.Code = csh.CaseStatus
--From the pivot data, get the list of field names (assumes description field is the source for the field name)
DECLARE @statusDescriptions VARCHAR(MAX)
SET @statusDescriptions = ''
SELECT @statusDescriptions = COALESCE(@statusDescriptions+'[','') + Description
FROM (
SELECT DISTINCT Description
FROM #StatusDates
WHERE Description IS NOT NULL
) x
SET @statusDescriptions = REPLACE(@statusDescriptions, '[', '],[') + ']'
SET @statusDescriptions = SUBSTRING(@statusDescriptions, 3, LEN(@statusDescriptions))
--Create a SQL statement to pivot the data into the fields.
DECLARE @sql VARCHAR(MAX)
SET @SQL = '
SELECT *
FROM #StatusDates
PIVOT(MIN(EventDt)
FOR Description IN (' + @statusDescriptions + '))
AS PVTTable '
PRINT @sql
EXEC(@sql)
DROP TABLE #StatusDates