条件语句对 CTE 很重要
Conditional statement counts with CTE
我使用下面提供的查询获得以下 table 作为输出。
下面是我使用的查询。
;WITH cte AS (
SELECT c.CaseID AS 'Case #',
m.ManufacturerName,
ou.OutcomeName
FROM Consumes con
INNER JOIN [Case] c
ON con.FKCaseID = c.CaseID
INNER JOIN Manufacturer m
ON m.ManufacturerID = con.FKManufacturerID
INNER JOIN Case_Outcome oc
ON oc.FKCaseID = c.CaseID
INNER JOIN OutCome ou
ON oc.FKOutcomeID = ou.OutcomeID
)
SELECT c.[Case #],
c.ManufacturerName,
STUFF((SELECT ','+OutcomeName
FROM cte
WHERE c.[Case #] = [Case #]
FOR XML PATH('')),1,1,'') as OutcomeName
FROM cte c
GROUP BY c.[Case #],c.ManufacturerNAme
我需要获得以下输出。
这里的事件数是每个制造商的案例数。有没有一种方法可以在不对 where 条件下的每个输出使用 CTE 的情况下获得上述输出?如果是这样,请协助举例。
我使用了答案中发布的以下查询,但结果百分比始终为 0% 或 100%。也就是说,如果案件的结果都是一样的,那么这很好。
SELECT
m.ManufacturerName,
COUNT(c.CaseID) AS '# Events',
COUNT(CASE WHEN ou.OutcomeName = 'Death' THEN c.CaseID ELSE NULL END) /COUNT(c.CaseID)*100.0 AS 'Death Events',
COUNT(CASE WHEN ou.OutcomeName = 'Hospitalization' THEN c.CaseID ELSE NULL END)/COUNT(c.CaseID)*100.0 AS 'Hospitalization Events',
COUNT(CASE WHEN ou.OutcomeName = 'Life Threatening' THEN c.CaseID ELSE NULL END)/COUNT(c.CaseID)*100.0 AS 'Life Threatening Events',
COUNT(CASE WHEN ou.OutcomeName = 'Disability' THEN c.CaseID ELSE NULL END)/COUNT(c.CaseID)*100.0 AS 'Disability Events',
COUNT(CASE WHEN ou.OutcomeName = 'Congenital Anomaly' THEN c.CaseID ELSE NULL END)/COUNT(c.CaseID)*100.0 AS 'Congenital Anomaly Events',
COUNT(CASE WHEN ou.OutcomeName = 'Required Intervention' THEN c.CaseID ELSE NULL END)/COUNT(c.CaseID)*100.0 AS 'Required Intervention Events',
COUNT(CASE WHEN ou.OutcomeName = 'Other Serious' THEN c.CaseID ELSE NULL END)/COUNT(c.CaseID)*100.0 AS 'Other Serious Events'
FROM Consumes con
INNER JOIN [Case] c ON con.FKCaseID = c.CaseID
INNER JOIN Manufacturer m ON m.ManufacturerID = con.FKManufacturerID
INNER JOIN Case_Outcome oc ON oc.FKCaseID = c.CaseID
INNER JOIN OutCome ou ON oc.FKOutcomeID = ou.OutcomeID
GROUP BY m.ManufacturerName
但是当结果不同时,它就不是 return 正确答案。以下是每种情况下我得到的计数。
但我的百分比结果集如下所示。
更新:(解决了舍入问题 - 在 COUNT() 前面移动了 100.00)
SELECT
m.ManufacturerName,
COUNT(DISTINCT c.CaseID),
100.0 * COUNT(DISTINCT CASE WHEN ou.OutcomeName = 'Death' THEN c.CaseID ELSE NULL END) / COUNT(DISTINCT c.CaseID),
100.0 * COUNT(DISTINCT CASE WHEN ou.OutcomeName = 'Hospitalization' THEN c.CaseID ELSE NULL END) / COUNT(DISTINCT c.CaseID),
100.0 * COUNT(DISTINCT CASE WHEN ou.OutcomeName = 'Life Threatening' THEN c.CaseID ELSE NULL END) / COUNT(DISTINCT c.CaseID)
FROM Consumes con
INNER JOIN [Case] c ON con.FKCaseID = c.CaseID
INNER JOIN Manufacturer m ON m.ManufacturerID = con.FKManufacturerID
INNER JOIN Case_Outcome oc ON oc.FKCaseID = c.CaseID
INNER JOIN OutCome ou ON oc.FKOutcomeID = ou.OutcomeID
GROUP BY m.ManufacturerName
HAVING COUNT(DISTINCT c.CaseID) <> 0
如果您需要显示所有类别的事件为零的制造商,请删除 Having 并添加语句来处理 'Division by zero'。还要为所有输出列添加别名。
更新:
如果要求只使用CTE的输出,那么数据可以这样转换:
declare @sql NVARCHAR(MAX) = '
declare @temp table (case_id varchar(100), manufacture varchar(1000), outcome varchar(max))
insert into @temp
'
select @sql = @sql + 'select ''' + t.case_id + ''', ''' + t.Manufacture + ''', s.Data from dbo.Split(''' + t.outcome + ''', '','') s union all' + char(13) + char(10)
from @t t
set @sql = LEFT(@sql, len(@sql) - 12) + char(13) + char(10) + char(13) + char(10)
set @sql = @sql + 'select * from @temp'
--print @sql
exec (@sql)
您需要实现 Split 功能(许多实现可用)。
根据您的设计更改列名称。
EXEC 的输出可以插入到 temp table
INSERT #TEMP (...)
EXEC (@SQL)
或者,您可以遍历 CTE 输出的每个值并使用 Split 函数获取 table 的值,并填充温度 table.
最后使用前面评论中提到的方法,或者使用列数未知的 PIVOT 函数,如下所述:Efficiently convert rows to columns in sql server
我使用下面提供的查询获得以下 table 作为输出。
下面是我使用的查询。
;WITH cte AS (
SELECT c.CaseID AS 'Case #',
m.ManufacturerName,
ou.OutcomeName
FROM Consumes con
INNER JOIN [Case] c
ON con.FKCaseID = c.CaseID
INNER JOIN Manufacturer m
ON m.ManufacturerID = con.FKManufacturerID
INNER JOIN Case_Outcome oc
ON oc.FKCaseID = c.CaseID
INNER JOIN OutCome ou
ON oc.FKOutcomeID = ou.OutcomeID
)
SELECT c.[Case #],
c.ManufacturerName,
STUFF((SELECT ','+OutcomeName
FROM cte
WHERE c.[Case #] = [Case #]
FOR XML PATH('')),1,1,'') as OutcomeName
FROM cte c
GROUP BY c.[Case #],c.ManufacturerNAme
我需要获得以下输出。
这里的事件数是每个制造商的案例数。有没有一种方法可以在不对 where 条件下的每个输出使用 CTE 的情况下获得上述输出?如果是这样,请协助举例。
我使用了答案中发布的以下查询,但结果百分比始终为 0% 或 100%。也就是说,如果案件的结果都是一样的,那么这很好。
SELECT
m.ManufacturerName,
COUNT(c.CaseID) AS '# Events',
COUNT(CASE WHEN ou.OutcomeName = 'Death' THEN c.CaseID ELSE NULL END) /COUNT(c.CaseID)*100.0 AS 'Death Events',
COUNT(CASE WHEN ou.OutcomeName = 'Hospitalization' THEN c.CaseID ELSE NULL END)/COUNT(c.CaseID)*100.0 AS 'Hospitalization Events',
COUNT(CASE WHEN ou.OutcomeName = 'Life Threatening' THEN c.CaseID ELSE NULL END)/COUNT(c.CaseID)*100.0 AS 'Life Threatening Events',
COUNT(CASE WHEN ou.OutcomeName = 'Disability' THEN c.CaseID ELSE NULL END)/COUNT(c.CaseID)*100.0 AS 'Disability Events',
COUNT(CASE WHEN ou.OutcomeName = 'Congenital Anomaly' THEN c.CaseID ELSE NULL END)/COUNT(c.CaseID)*100.0 AS 'Congenital Anomaly Events',
COUNT(CASE WHEN ou.OutcomeName = 'Required Intervention' THEN c.CaseID ELSE NULL END)/COUNT(c.CaseID)*100.0 AS 'Required Intervention Events',
COUNT(CASE WHEN ou.OutcomeName = 'Other Serious' THEN c.CaseID ELSE NULL END)/COUNT(c.CaseID)*100.0 AS 'Other Serious Events'
FROM Consumes con
INNER JOIN [Case] c ON con.FKCaseID = c.CaseID
INNER JOIN Manufacturer m ON m.ManufacturerID = con.FKManufacturerID
INNER JOIN Case_Outcome oc ON oc.FKCaseID = c.CaseID
INNER JOIN OutCome ou ON oc.FKOutcomeID = ou.OutcomeID
GROUP BY m.ManufacturerName
但是当结果不同时,它就不是 return 正确答案。以下是每种情况下我得到的计数。
但我的百分比结果集如下所示。
更新:(解决了舍入问题 - 在 COUNT() 前面移动了 100.00)
SELECT
m.ManufacturerName,
COUNT(DISTINCT c.CaseID),
100.0 * COUNT(DISTINCT CASE WHEN ou.OutcomeName = 'Death' THEN c.CaseID ELSE NULL END) / COUNT(DISTINCT c.CaseID),
100.0 * COUNT(DISTINCT CASE WHEN ou.OutcomeName = 'Hospitalization' THEN c.CaseID ELSE NULL END) / COUNT(DISTINCT c.CaseID),
100.0 * COUNT(DISTINCT CASE WHEN ou.OutcomeName = 'Life Threatening' THEN c.CaseID ELSE NULL END) / COUNT(DISTINCT c.CaseID)
FROM Consumes con
INNER JOIN [Case] c ON con.FKCaseID = c.CaseID
INNER JOIN Manufacturer m ON m.ManufacturerID = con.FKManufacturerID
INNER JOIN Case_Outcome oc ON oc.FKCaseID = c.CaseID
INNER JOIN OutCome ou ON oc.FKOutcomeID = ou.OutcomeID
GROUP BY m.ManufacturerName
HAVING COUNT(DISTINCT c.CaseID) <> 0
如果您需要显示所有类别的事件为零的制造商,请删除 Having 并添加语句来处理 'Division by zero'。还要为所有输出列添加别名。
更新:
如果要求只使用CTE的输出,那么数据可以这样转换:
declare @sql NVARCHAR(MAX) = '
declare @temp table (case_id varchar(100), manufacture varchar(1000), outcome varchar(max))
insert into @temp
'
select @sql = @sql + 'select ''' + t.case_id + ''', ''' + t.Manufacture + ''', s.Data from dbo.Split(''' + t.outcome + ''', '','') s union all' + char(13) + char(10)
from @t t
set @sql = LEFT(@sql, len(@sql) - 12) + char(13) + char(10) + char(13) + char(10)
set @sql = @sql + 'select * from @temp'
--print @sql
exec (@sql)
您需要实现 Split 功能(许多实现可用)。 根据您的设计更改列名称。 EXEC 的输出可以插入到 temp table
INSERT #TEMP (...)
EXEC (@SQL)
或者,您可以遍历 CTE 输出的每个值并使用 Split 函数获取 table 的值,并填充温度 table.
最后使用前面评论中提到的方法,或者使用列数未知的 PIVOT 函数,如下所述:Efficiently convert rows to columns in sql server