【问题标题】:Conditional statement counts with CTECTE 条件语句计数
【发布时间】:2016-08-15 00:57:31
【问题描述】:

我使用下面提供的查询获得下表作为输出。

以下是我使用的查询。

;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

我需要得到下面的输出。

这里的事件数是每个制造商的 case# 计数。有没有一种方法可以获得上述输出,而无需在 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

但是当结果不同时,它不会返回正确的答案。以下是我在每种情况下得到的计数。

但我的百分比结果集如下所示。

【问题讨论】:

  • 我不明白这个问题。您的查询中实际上没有 where 条件(除了相关子句)。

标签: sql sql-server sql-server-2012 where-clause common-table-expression


【解决方案1】:

更新:(修复了舍入问题 - 在 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

如果您需要显示所有类别的事件为零的制造商,请删除 Have 并添加语句以处理“除以零”。还要为所有输出列添加别名。

更新:

如果要求只使用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)

您需要实现拆分功能(许多实现可用)。 根据您的设计更改列名称。 EXEC的输出可以插入到临时表中

INSERT #TEMP (...)
EXEC (@SQL)

或者,您可以循环遍历 CTE 输出的每个值,并使用 Split 函数获取包含值的表,并填充临时表。

最后还是使用前面cmets中提到的方法,或者使用PIVOT函数,列数未知,这里描述:Efficiently convert rows to columns in sql server

【讨论】:

  • 当一个案例的所有结果都相同时,这可以正常工作。当同一案例有多个结果时,这不会给出正确的输出。我已经用我得到的输出编辑了这个问题。
  • 我没有机会检查我的脚本,因为您没有提供表格的定义。问题很小 - 这是因为四舍五入 - 只需将“* 100.00”移动到“COUNT(...”之前。“select 3/9 * 100.0”与“100.0 * 3 / 9”不同
  • 嘿,无需对案例进行硬编码,有没有办法可以从结果列的逗号分隔值中提取它们并从中计算百分比?
  • 是的,可以通过多种方式实现。对我来说最简单的是将结果值提取到临时表#t,然后声明 NVARCHAR(MAX)“@sql”变量,将其设置为“SELECT m.ManufacturerName, COUNT(DISTINCT c.CaseID)”,构建该变量比如从#t中选择“@sql”=“@sql”+'100.00 * COUNT... WHEN coucome = #t.value THEN ...,'。然后删除最后一个逗号,然后添加其余代码'FROM ....',然后将其作为动态sql执行。您可以将结果插入到另一个临时表中。
  • 你能提供一个使用xml或cte的例子吗? :(
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2017-09-06
  • 2019-03-03
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多