SQL Select语句中的动态子选择

时间:2014-10-09 22:57:01

标签: sql reporting-services ssrs-2008

我正在查询表格以获取一些基本信息,文件编号,案例类型,状态等。此外,我需要为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个选择语句?

2 个答案:

答案 0 :(得分:0)

这将非常缓慢 - 138个相关的子查询。我认为您可以使用OUTER JOINGROUP 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方法。除非PhoneWritten在另一列中,否则我不完全确定如何使用动态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
相关问题