如何通过rollup()查询在组中添加平均列

时间:2014-07-21 22:36:19

标签: sql tsql

我需要在一个相当简单的查询中显示平均值,但我不确定如何在此上下文中获得一个。要求是显示在医疗程序中获得的样本数量(由医生,然后通过程序)。

我目前有一个查询可以得到这个结果:

+----------------------+-------------+------------+------------------+
|       Physician      |  Procedure  | Total Jars | Total Encounters |
+----------------------+-------------+------------+------------------+
| NULL                 | NULL        |        531 |              790 |
| Smith MD, Benjamin A | NULL        |        531 |              790 |
| Smith MD, Benjamin A | Procedure A |        379 |              581 |
| Smith MD, Benjamin A | Procedure B |        128 |              180 |
| Smith MD, Benjamin A | Procedure C |         24 |               29 |
+----------------------+-------------+------------+------------------+

列表中当然会有更多的医生,所以汇总会更有帮助。还需要的是获得的平均罐子数量(再次由医生和程序)。

我会在此处提供我的查询,但我觉得我最好多给一些背景信息,以防万一与任何可能的推荐相关。

'Total Jars'数据存储在12个表中,这些表都包含相同的字段,从一开始就应该是一个表。我知道这是糟糕的设计,但这就是我现在必须要做的事情。

对于每次遭遇,可能会有0到12个样本,所以为了引入数据,我在CTE上进行左连接,这实际上只是属于搜索的任何记录的一个大UNION标准。因为我没有在单个表记录中获得的样本总数(每次遭遇),所以我不能做一个简单的AVG。

如果有关如何最好地将平均值纳入查询的任何建议,我将不胜感激。这是我目前的查询:

DECLARE  @start_date VARCHAR(8)
        ,@end_date VARCHAR(8)
        ,@practice_id CHAR(4)

SET      @start_date = '20130601'
SET      @end_date = '20140601'
SET      @practice_id = '0001'

;WITH jars
AS
(
SELECT      pe.enc_id AS enc_id
FROM        patient_encounter pe
INNER JOIN  Bottle_1_ b1 ON pe.enc_id = b1.enc_id
AND         pe.enc_timestamp BETWEEN @start_date AND @end_date
AND         ISNULL(b1.eso1, '') <> ''
UNION ALL
SELECT      pe.enc_id AS enc_id
FROM        patient_encounter pe
INNER JOIN  Bottle2_ b2 ON pe.enc_id = b2.enc_id
AND         pe.enc_timestamp BETWEEN @start_date AND @end_date
AND         ISNULL(b2.eso1, '') <> ''
UNION ALL
SELECT      pe.enc_id AS enc_id
FROM        patient_encounter pe
INNER JOIN  Bottle3_ b3 ON pe.enc_id = b3.enc_id
AND         pe.enc_timestamp BETWEEN @start_date AND @end_date
AND         ISNULL(b3.eso1, '') <> ''
UNION ALL
SELECT      pe.enc_id AS enc_id
FROM        patient_encounter pe
INNER JOIN  Bottle4_ b4 ON pe.enc_id = b4.enc_id
AND         pe.enc_timestamp BETWEEN @start_date AND @end_date
AND         ISNULL(b4.eso1, '') <> ''
UNION ALL
SELECT      pe.enc_id AS enc_id
FROM        patient_encounter pe
INNER JOIN  Bottle5_ b5 ON pe.enc_id = b5.enc_id
AND         pe.enc_timestamp BETWEEN @start_date AND @end_date
AND         ISNULL(b5.eso1, '') <> ''
UNION ALL
SELECT      pe.enc_id AS enc_id
FROM        patient_encounter pe
INNER JOIN  Bottle6_ b6 ON pe.enc_id = b6.enc_id
AND         pe.enc_timestamp BETWEEN @start_date AND @end_date
AND         ISNULL(b6.eso1, '') <> ''
UNION ALL
SELECT      pe.enc_id AS enc_id
FROM        patient_encounter pe
INNER JOIN  Bottle7_ b7 ON pe.enc_id = b7.enc_id
AND         pe.enc_timestamp BETWEEN @start_date AND @end_date
AND         ISNULL(b7.eso1, '') <> ''
UNION ALL
SELECT      pe.enc_id AS enc_id
FROM        patient_encounter pe
INNER JOIN  Bottle8_ b8 ON pe.enc_id = b8.enc_id
AND         pe.enc_timestamp BETWEEN @start_date AND @end_date
AND         ISNULL(b8.eso1, '') <> ''
UNION ALL
SELECT      pe.enc_id AS enc_id
FROM        patient_encounter pe
INNER JOIN  Bottle9_ b9 ON pe.enc_id = b9.enc_id
AND         pe.enc_timestamp BETWEEN @start_date AND @end_date
AND         ISNULL(b9.eso1, '') <> ''
UNION ALL
SELECT      pe.enc_id AS enc_id
FROM        patient_encounter pe
INNER JOIN  Bottle10_ b10 ON pe.enc_id = b10.enc_id
AND         pe.enc_timestamp BETWEEN @start_date AND @end_date
AND         ISNULL(b10.eso1, '') <> ''
UNION ALL
SELECT      pe.enc_id AS enc_id
FROM        patient_encounter pe
INNER JOIN  Bottle11_ b11 ON pe.enc_id = b11.enc_id
AND         pe.enc_timestamp BETWEEN @start_date AND @end_date
AND         ISNULL(b11.eso1, '') <> ''
UNION ALL
SELECT      pe.enc_id AS enc_id
FROM        patient_encounter pe
INNER JOIN  Bottle12_ b12 ON pe.enc_id = b12.enc_id
AND         pe.enc_timestamp BETWEEN @start_date AND @end_date
AND         ISNULL(b12.eso1, '') <> ''
)

SELECT              pm.description AS [Physician],
                    e.event AS [Procedure],
                    COUNT(j.enc_id) AS [Total Jars],
                    COUNT(pe.enc_id) AS [Total Encounters]
FROM                patient_encounter pe
INNER JOIN          person p ON pe.person_id = p.person_id AND pe.practice_id = @practice_id
INNER JOIN          appointments ap ON pe.enc_id = ap.enc_id
                                    AND ap.resched_ind = 'N'
                                    AND ap.delete_ind = 'N'
                                    AND ap.cancel_ind = 'N'
                                    AND ap.appt_kept_ind = 'Y'
INNER JOIN          events e ON ap.event_id = e.event_id
INNER JOIN          provider_mstr pm ON pe.rendering_provider_id = pm.provider_id
INNER JOIN          location_mstr lm ON pe.location_id = lm.location_id
LEFT JOIN           (SELECT enc_id
                     FROM jars
                     GROUP BY enc_id) AS j ON pe.enc_id = j.enc_id
WHERE               pe.enc_timestamp BETWEEN @start_date AND @end_date
GROUP BY GROUPING SETS
    ( (pm.description, e.event)
      ,ROLLUP(pm.description)
    )
ORDER BY pm.description, e.event

此外,我正在使用Microsoft SQL Server 2008 R2。

1 个答案:

答案 0 :(得分:0)

你可以用ROLLUP:

来做
;WITH jars
AS
(
SELECT      pe.enc_id AS enc_id
FROM        patient_encounter pe
INNER JOIN  Bottle_1_ b1 ON pe.enc_id = b1.enc_id
AND         pe.enc_timestamp BETWEEN @start_date AND @end_date
AND         ISNULL(b1.eso1, '') <> ''
UNION ALL
SELECT      pe.enc_id AS enc_id
FROM        patient_encounter pe
INNER JOIN  Bottle2_ b2 ON pe.enc_id = b2.enc_id
AND         pe.enc_timestamp BETWEEN @start_date AND @end_date
AND         ISNULL(b2.eso1, '') <> ''
UNION ALL
SELECT      pe.enc_id AS enc_id
FROM        patient_encounter pe
INNER JOIN  Bottle3_ b3 ON pe.enc_id = b3.enc_id
AND         pe.enc_timestamp BETWEEN @start_date AND @end_date
AND         ISNULL(b3.eso1, '') <> ''
UNION ALL
SELECT      pe.enc_id AS enc_id
FROM        patient_encounter pe
INNER JOIN  Bottle4_ b4 ON pe.enc_id = b4.enc_id
AND         pe.enc_timestamp BETWEEN @start_date AND @end_date
AND         ISNULL(b4.eso1, '') <> ''
UNION ALL
SELECT      pe.enc_id AS enc_id
FROM        patient_encounter pe
INNER JOIN  Bottle5_ b5 ON pe.enc_id = b5.enc_id
AND         pe.enc_timestamp BETWEEN @start_date AND @end_date
AND         ISNULL(b5.eso1, '') <> ''
UNION ALL
SELECT      pe.enc_id AS enc_id
FROM        patient_encounter pe
INNER JOIN  Bottle6_ b6 ON pe.enc_id = b6.enc_id
AND         pe.enc_timestamp BETWEEN @start_date AND @end_date
AND         ISNULL(b6.eso1, '') <> ''
UNION ALL
SELECT      pe.enc_id AS enc_id
FROM        patient_encounter pe
INNER JOIN  Bottle7_ b7 ON pe.enc_id = b7.enc_id
AND         pe.enc_timestamp BETWEEN @start_date AND @end_date
AND         ISNULL(b7.eso1, '') <> ''
UNION ALL
SELECT      pe.enc_id AS enc_id
FROM        patient_encounter pe
INNER JOIN  Bottle8_ b8 ON pe.enc_id = b8.enc_id
AND         pe.enc_timestamp BETWEEN @start_date AND @end_date
AND         ISNULL(b8.eso1, '') <> ''
UNION ALL
SELECT      pe.enc_id AS enc_id
FROM        patient_encounter pe
INNER JOIN  Bottle9_ b9 ON pe.enc_id = b9.enc_id
AND         pe.enc_timestamp BETWEEN @start_date AND @end_date
AND         ISNULL(b9.eso1, '') <> ''
UNION ALL
SELECT      pe.enc_id AS enc_id
FROM        patient_encounter pe
INNER JOIN  Bottle10_ b10 ON pe.enc_id = b10.enc_id
AND         pe.enc_timestamp BETWEEN @start_date AND @end_date
AND         ISNULL(b10.eso1, '') <> ''
UNION ALL
SELECT      pe.enc_id AS enc_id
FROM        patient_encounter pe
INNER JOIN  Bottle11_ b11 ON pe.enc_id = b11.enc_id
AND         pe.enc_timestamp BETWEEN @start_date AND @end_date
AND         ISNULL(b11.eso1, '') <> ''
UNION ALL
SELECT      pe.enc_id AS enc_id
FROM        patient_encounter pe
INNER JOIN  Bottle12_ b12 ON pe.enc_id = b12.enc_id
AND         pe.enc_timestamp BETWEEN @start_date AND @end_date
AND         ISNULL(b12.eso1, '') <> ''
),
totals AS(
SELECT              pm.description AS [Physician],
                    e.event AS [Procedure],
                    COUNT(j.enc_id) AS [Total Jars],
                    COUNT(pe.enc_id) AS [Total Encounters],
                    CASE WHEN COUNT(pe.enc_id) <> 0 THEN CONVERT(float, COUNT(j.enc_id))/CONVERT(float, COUNT(pe.enc_id)) ELSE 0 END AS [AvgTotal]
FROM                patient_encounter pe
INNER JOIN          person p ON pe.person_id = p.person_id AND pe.practice_id = @practice_id
INNER JOIN          appointments ap ON pe.enc_id = ap.enc_id
                                    AND ap.resched_ind = 'N'
                                    AND ap.delete_ind = 'N'
                                    AND ap.cancel_ind = 'N'
                                    AND ap.appt_kept_ind = 'Y'
INNER JOIN          events e ON ap.event_id = e.event_id
INNER JOIN          provider_mstr pm ON pe.rendering_provider_id = pm.provider_id
INNER JOIN          location_mstr lm ON pe.location_id = lm.location_id
LEFT JOIN           (SELECT enc_id
                     FROM jars
                     GROUP BY enc_id) AS j ON pe.enc_id = j.enc_id
WHERE               pe.enc_timestamp BETWEEN @start_date AND @end_date
GROUP pm.description, e.event)
SELECT [Physician], [Procedure], 
       Avg([Total Jars]) [Total Jars], 
       Avg([Total Encounters]) [Total Encounters], 
       Avg([AvgTotal]) [AvgTotal]
from totals
GROUP BY [Physician], [Procedure]
WITH ROLLUP