首页 > 解决方案 > 使用案例表达式获取每个条件的计数和百分比

问题描述

我想要一个类似于下表的输出,我可以在其中使用 Case 表达式从查询中获取计数和百分比。表中的数字仅用于说明目的。

年龄阶层 数数 百分比
沉默的 1 10%
婴儿潮一代 2 20%
一代 1 10%
千禧一代 4 40%
Z世代 2 20%

我运行了以下查询:

SELECT 
    COUNT(CASE
        WHEN birth_year between 1928 and 1945 THEN 'Silent'
        WHEN birth_year between 1946 and 1964 THEN 'Boomers'
        WHEN birth_year between 1965 and 1980 THEN 'Generation X'
        WHEN birth_year between 1981 and 1996 THEN 'Millennial'
        WHEN birth_year between 1997 and 2012 THEN 'Generation Z'
        ELSE 'Other'
    END) as 'AgeGroup'
    FROM CombinedTable

输出给了我不是我想要的总数。

注意: 我使用的是 Microsoft SQL Server 2017

标签: sqlsql-servertsql

解决方案


您需要按该CASE表达式分组。您可以将其放在 aCROSS APPLY中以避免重复。

VALUES返回一个虚拟表,如果你使用CROSS APPLY它,你可以将它加入每一行,同时能够从以前引用的表中插入值

SELECT
  v.AgeGroup, 
  COUNT(*) AS Count,
  COUNT(*) * 100.0 / SUM(COUNT(*)) OVER () AS Percentage
FROM CombinedTable ct
CROSS APPLY (VALUES (
    CASE
        WHEN birth_year between 1928 and 1945 THEN 'Silent'
        WHEN birth_year between 1946 and 1964 THEN 'Boomers'
        WHEN birth_year between 1965 and 1980 THEN 'Generation X'
        WHEN birth_year between 1981 and 1996 THEN 'Millennial'
        WHEN birth_year between 1997 and 2012 THEN 'Generation Z'
        ELSE 'Other'
    END
)) v(AgeGroup)
GROUP BY
  v.AgeGroup;

这也更容易通过连接来完成

在这种情况下,我们构建了一个可能选项的虚拟表,并以正常方式将其连接到每一行

SELECT
  ISNULL(v.AgeGroup, 'Other') AS AgeGroup, 
  COUNT(*) AS Count,
  COUNT(*) * 100.0 / SUM(COUNT(*)) OVER () AS Percentage
FROM CombinedTable ct
LEFT JOIN (VALUES
    (1928,1945,'Silent'),
    (1946,1964,'Boomers'),
    (1965,1980,'Generation X'),
    (1981,1996,'Millennial'),
    (1997,2012,'Generation Z')
) v(StartYear, EndYear, AgeGroup) ON tc.birth_year BETWEEN v.StartYear AND v.EndYear
GROUP BY
  ISNULL(v.AgeGroup, 'Other');

推荐阅读