从记录状态计算几个百分比

时间:2018-01-12 17:28:41

标签: sql sql-server

简而言之:我想根据另一个表中记录的状态计算多个百分比。

很长时间:大家好,我遇到的问题是,我试图根据有多少测试来计算一堆百分比,而不是根据总数可能进行管理,以及由于报告原因已完成/拒绝了多少,我不确定最佳方法。

例如,我有两个主要的表:

Assessment +---------------+--------+---------+---------+ | Assessment_ID | Date | Test_FK | Dept_FK | +---------------+--------+---------+---------+ | 1 | 1/1/18 | 1 | 1 | | 2 | 1/1/18 | 2 | 1 | | 3 | 1/2/18 | 3 | 1 | | 4 | 1/4/18 | 4 | 2 | | 5 | 1/2/18 | 5 | 2 | | 6 | 1/2/18 | 6 | 2 | | 7 | 1/3/18 | 7 | 2 | +---------------+--------+---------+---------+

Test +---------+----------------+------------+------------+ | Test_ID | IsAdministered | IsComplete | IsDeclined | +---------+----------------+------------+------------+ | 1 | 1 | 1 | 0 | | 2 | 1 | 0 | 1 | | 3 | 1 | 1 | 0 | | 4 | 1 | 1 | 0 | | 5 | 1 | 0 | 1 | | 6 | 0 | 0 | 0 | | 7 | 0 | 0 | 0 | +---------+----------------+------------+------------+

......不是一个真正的关键因素,但我想提一下这个因素,因为它会淘汰可能被错误归因于不同部门的测试......

Assessment_Test_Eligbility_Lookup +---------+-----------+----------+ | Dept_FK | DateStart | DateEnd | +---------+-----------+----------+ | 1 | 1/1/2017 | 1/1/2020 | | 2 | 1/1/2017 | 1/1/2020 | +---------+-----------+----------+

...使用查找表跟踪哪些评估符合进行测试的条件。从这里开始,我想了解以下内容:

SELECT
    dept.name,
    CONCAT(MONTH(enc.Encounter_Date), '-', YEAR(enc.Encounter_Date)),
    COUNT(Tests.IsAdministered = 1) / COUNT(Tests) 'Administered %',
    COUNT(Tests.IsComplete = 1) / COUNT(Tests.IsAdministered = 1) 'Completed %',
    COUNT(Tests.IsDeclined = 1) / COUNT(Tests.IsAdministered = 1) 'Declined %'
FROM
    DEPT
    JOIN Assessment ON Dept_ID = Dept_FK
    JOIN Test ON Test_ID = Test_FK
    JOIN Assessment_Test_Eligability_Lookup ON Dept_ID = Dept_FK 
       AND Date BETWEEN DateStart AND DateEnd

不幸的是,在此之后,我不确定如何最好地继续下去。大多数是因为查找表相当大并且多次连接它可能需要一个年龄才能完成。

预期输出示例:

+---------+------------+----------------+----------------+----------------------+---------------------+
| Dept_ID | Month/Year | Total Possible | Administered % | Completed % of Admin | Declined % of Admin |
+---------+------------+----------------+----------------+----------------------+---------------------+
|       1 | 1-2018     |              3 |            100 |                   66 |                  33 |
|       2 | 1-2018     |              4 |             50 |                   50 |                  50 |
+---------+------------+----------------+----------------+----------------------+---------------------+

对此有何想法?非常感谢!

1 个答案:

答案 0 :(得分:0)

以下是使用一些示例数据执行此类操作的几种方法。确保处理零除错误!

DECLARE @Test TABLE (Encounter_Date datetime, IsAdministered bit, IsComplete bit, IsDeclined bit)
INSERT INTO @Test VALUES (GETDATE() - 10, 0, 0, 0)
INSERT INTO @Test VALUES (GETDATE() - 9, 0, 0, 0)
INSERT INTO @Test VALUES (GETDATE() - 8, 1, 1, 0)
INSERT INTO @Test VALUES (GETDATE() - 7, 1, 1, 0)
INSERT INTO @Test VALUES (GETDATE() - 6, 1, 1, 0)
INSERT INTO @Test VALUES (GETDATE() - 5, 1, 1, 0)
INSERT INTO @Test VALUES (GETDATE() - 4, 1, 0, 0)
INSERT INTO @Test VALUES (GETDATE() - 3, 1, 0, 0)
INSERT INTO @Test VALUES (GETDATE() - 2, 1, 0, 1)
INSERT INTO @Test VALUES (GETDATE() - 1, 1, 0, 1)

SELECT
CONCAT(MONTH(Encounter_Date), '-', YEAR(Encounter_Date)) AS "Month / Year",
AVG(CAST(IsAdministered AS NUMERIC(3,2))) 'Administered %',
CAST(COUNT(NULLIF(IsComplete, 0)) AS NUMERIC(3,2)) 
    / CAST(COUNT(CASE WHEN IsAdministered = 0 THEN NULL ELSE 1 END) AS NUMERIC(3,2)) AS 'Completed %',
SUM(CAST(IsDeclined AS NUMERIC(3,2)))
    / SUM(CAST(IsAdministered AS NUMERIC(3,2))) AS 'Declined %'
FROM @Test
GROUP BY MONTH(Encounter_Date), YEAR(Encounter_Date)

输出:

Month / Year    Administered %  Completed % Declined %
1-2018          0.800000        0.500000    0.250000

您的示例DDL未显示名为Encounter_Date的列,并且您的查询没有作为测试别名的表,但如果您修复了表别名,则这是您的查询:

SELECT
    dept.Name,
    CONCAT(MONTH(Encounter_Date), '-', YEAR(Encounter_Date)) AS 'Month/Year',
    CAST(COUNT(NULLIF(Test.IsAdministered, 0)) AS NUMERIC(3,2))  / COUNT(*) 'Administered %',
    CAST(COUNT(NULLIF(Test.IsComplete, 0)) AS NUMERIC(3,2))  / COUNT(NULLIF(Test.IsAdministered, 0)) 'Completed %',
    CAST(COUNT(NULLIF(Test.IsDeclined, 0)) AS NUMERIC(3,2))  / COUNT(NULLIF(Test.IsAdministered, 0)) 'Declined %'
FROM
    DEPT
    JOIN Assessment ON Dept_ID = Dept_FK
    JOIN Test ON Test_ID = Test_FK
    JOIN Assessment_Test_Eligibility_Lookup ON Dept_ID = Assessment_Test_Eligibility_Lookup.Dept_FK 
       AND Encounter_Date BETWEEN DateStart AND DateEnd
GROUP BY Dept.Name, MONTH(Encounter_Date), YEAR(Encounter_Date)

输出:

Name    Month/Year  Administered %  Completed % Declined %
Dept 1  1-2018      1.00            0.66      0.33
Dept 2  1-2018      0.50            0.500     0.50