条件语句计入CTE

时间:2016-08-15 00:57:32

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

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

enter image description here

以下是我使用的查询。

;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

我需要得到以下输出。

enter image description here

此处的事件数是每个制造商的案例数#。有没有办法可以在不使用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

但是当结果不同时,它不会返回正确的答案。以下是我为每个案例得到的计数。

enter image description here

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

enter image description here

1 个答案:

答案 0 :(得分: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

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

更新:

如果要求仅使用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的输出可以插入临时表

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

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

最后使用评论中前面提到的方法,或使用PIVOT函数,其中列数未知,如下所述:Efficiently convert rows to columns in sql server