2017-02-15 5 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 

Что я необходимость делать также вычислить Sub Всего проценты, так например, первый Sub Total равен 1295, так что будет вычисляться процент от 1295 + 5236 + 2934 и получить значение 13,68% и т. д. для других строк Sub Total.

Как это можно сделать динамически, так что независимо от количества Sub Totals он рассчитает его правильно?

+0

вы пробовали делать SELECT, ISNULL (DrugName, 'Sub Total:') as Drug, SUM (COUNT) as Count, SUM (В процентах)/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

@James из моего понимания, пожалуйста, положите свой результат 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. Ошибки, к сожалению, отсутствуют: Msg 130, уровень 15, состояние 1, строка 7 Невозможно выполнить агрегированную функцию для выражения, содержащего агрегат или подзапрос. – Philip

+0

Какую версию SQL Server вы используете? Мне удалось заставить его работать: http://rextester.com/FEZT88753 – shawnt00

+0

@ shawnt00 - когда я попробую ваш пример, столбец «Процент» равен 0? Использование экземпляра SQL Azure MSDN. – Philip

Смежные вопросы