2017-02-15 96 views
2

我有以下查询:SUM基于不同类型

SELECT 
    ISNULL(DrugName,'Sub Total:') as Drug, 
    SUM(COUNT) as Count, 
    Percentage 
FROM 
(
    SELECT 
     DrugName, 
     DrugCategoryName, 
     COUNT(*) as Count, 
     CONVERT(DECIMAL(10,2),COUNT(*) * 100.0/SUM(COUNT(*)) over()) as Percentage 
     FROM 
     Visit V 
    INNER JOIN Drug D on 
     V.DrugID = D.DrugID 
    INNER JOIN DrugCategory DC on 
     D.DrugCategoryID = DC.DrugCategoryID 
    GROUP BY GROUPING SETS 
     ((DrugName, DrugCategoryName)) 
) a 
GROUP BY GROUPING SETS 
    ((DrugName, DrugCategoryName, Percentage), (DrugCategoryName)) 

其结果如下:

Drug       Count Percentage 
Amphetamines     401 4.24 
Benzodiazapine     435 4.60 
Biodone       459 4.85 
Sub Total:      1295 NULL 
Brown Heroin     436 4.61 
Buprenorphine     396 4.18 
Cocaine       444 4.69 
Did not inject     404 4.27 
Endone       450 4.75 
Fentanyl Patch     404 4.27 
Heroin       1365 14.42 
Heroin & Cocaine    448 4.73 
Ice/Crystal/Meth    889 9.39 
Sub Total:      5236 NULL 
Kapanol       427 4.51 
Methadone      430 4.54 
Methadone Syrup     394 4.16 
Morphine      417 4.41 
MS Contin      438 4.63 
MS Mono       424 4.48 
Other Amphetamines    404 4.27 
Sub Total:      2934 NULL 

什么我也需要做的是计算小计百分比,所以例如第一个小计总计为1295,因此计算基于1295 + 5236 + 2934的百分比并获得13.68%的值,以此类推其他小计总计行。

这怎么能动态完成,所以无论小计总量是多少,它都能正确计算出来?

+0

你尝试过做SELECT ISNULL(DrugName, '小计:' )as Drug, SUM(COUNT)as Count, SUM(Percentage)/ SUM(COUNT)AS perc ...然后全部和以前一样 – Cato

+0

是的,我感谢@Cato - 没有好处。 – Philip

+0

您将需要在那里通过DrugCategoryName'订购。 – shawnt00

回答

1
WITH CTE AS 
(
SELECT 
    ISNULL(DrugName,'Sub Total:') as Drug, 
    SUM(COUNT) as Count, 
    Percentage 
FROM 
(
    SELECT 
     DrugName, 
     DrugCategoryName, 
     COUNT(*) as Count, 
     CONVERT(DECIMAL(10,2),COUNT(*) * 100.0/SUM(COUNT(*)) over()) as Percentage 
     FROM 
     Visit V 
    INNER JOIN Drug D on 
     V.DrugID = D.DrugID 
    INNER JOIN DrugCategory DC on 
     D.DrugCategoryID = DC.DrugCategoryID 
    GROUP BY GROUPING SETS 
     ((DrugName, DrugCategoryName)) 
) a 
GROUP BY GROUPING SETS 
    ((DrugName, DrugCategoryName, Percentage), (DrugCategoryName))) 

     SELECT [DRUG],[COUNT] ,ISNULL([PERCENTAGE],([COUNT]/S)*100) AS [PERCENTAGE] FROM CTE A CROSS APPLY 
    (SELECT CAST(SUM([COUNT])AS NUMERIC(22,6)) AS S FROM CTE B WHERE DRUG='SUB TOTAL:')C 

输出

DRUG COUNT PERCENTAGE 
Amphetamines 401 4.240000 
Benzodiazapine 435 4.600000 
Biodone 459 4.850000 
Sub Total: 1295 13.681986 
Brown Heroin 436 4.610000 
Buprenorphine 396 4.180000 
Cocaine 444 4.690000 
Did not inject 404 4.270000 
Endone 450 4.750000 
Fentanyl Patch 404 4.270000 
Heroin 1365 14.420000 
Heroin & Cocaine 448 4.730000 
Ice/Crystal/Meth 889 9.390000 
Sub Total: 5236 55.319599 
Kapanol 427 4.510000 
Methadone 430 4.540000 
Methadone Syrup 394 4.160000 
Morphine 417 4.410000 
MS Contin 438 4.630000 
MS Mono 424 4.480000 
Other Amphetamines 404 4.270000 
Sub Total: 2934 30.998415 
+0

谢谢@Chanukya,看起来工作得很好,但可能将其纳入原始查询? – Philip

+0

@詹姆斯从我的理解,请把你的结果cte和之后,你可以像我一样使用 – Chanukya

+0

公平的。我想看看这是否可以理想地避免。 – Philip

0

我想你可以只计算子查询的总及分:

SELECT COALESCE(DrugName, 'Sub Total:') as Drug, 
     SUM(COUNT) as Count, 
     SUM(COUNT)/total_cnt as Percentage 
FROM (SELECT DrugName, DrugCategoryName, 
      COUNT(*) as Count, 
      CONVERT(DECIMAL(10,2), COUNT(*)) * 100.0/SUM(COUNT(*)) over() as Percentage, 
      SUM(1.0*COUNT(*)) OVER() as total_cnt 
     FROM Visit V INNER JOIN 
      Drug D 
      ON V.DrugID = D.DrugID INNER JOIN 
      DrugCategory DC 
      ON D.DrugCategoryID = DC.DrugCategoryID 
     GROUP BY DrugName, DrugCategoryName 
    ) vd 
GROUP BY GROUPING SETS ((DrugName, DrugCategoryName, Percentage, Total_cnt), 
         (DrugCategoryName, Total_Cnt)) 
+0

谢谢@Gordon Linoff。它错误,但不幸的是: 消息130,级别15,状态1,行7 无法对包含聚合或子查询的表达式执行聚合函数。 – Philip

+0

您使用的是哪个版本的SQL Server?我能够得到它的工作:http://rextester.com/FEZT88753 – shawnt00

+0

@ shawnt00 - 当我尝试你的例子百分比列是0?使用MSDN SQL Azure实例。 – Philip