多列条件聚合

Posted

技术标签:

【中文标题】多列条件聚合【英文标题】:Multi-column Conditional Aggregation 【发布时间】:2015-08-17 22:07:10 【问题描述】:

在 SQL Server 2008 中。

我的东西的组件处于两种状态之一,表格如下所示:

create table Things (
    ThingName varchar(10),
    ItemNumber INT,
    ItemStatus varchar(10));

INSERT INTO Things (
    ThingName,
    ItemNumber,
    ItemStatus)
VALUES
    ('a', 1, 'red'),
    ('a', 2, 'red'),
    ('a', 3, 'blue'),
    ('b', 1, 'red'),
    ('b', 2, 'red'),
    ('b', 3, 'red'),
    ('b', 4, 'red'),
    ('c', 1, 'blue'),
    ('c', 2, 'blue'),
    ('c', 3, 'red');

我需要的每件事的结果是 1) 项目总数 2) 红色项目总数 3) 蓝色项目总数

结果如下:

ThingName    TotalItems    RedItems    BlueItems
    a            3            2            1
    b            4            4            0
    c            3            1            2

我用来执行此操作的“明显”查询:

SELECT
    ThingName,
    sum(Red + Blue) as TotalItems,
    sum(Red) as RedItems,
    sum(Blue) as BlueItems
FROM (
    SELECT
    ThingName,
    case
        when ItemStatus = 'red' then count(*)
        else 0
    end as Red,
    case
        when ItemStatus = 'blue' then count(*)
        else 0
    end as Blue
FROM Things
GROUP BY
    ThingName,
    ItemStatus) a GROUP BY ThingName;

这可行,但看起来很原始且不令人满意。实际上,我似乎看不到如何在不采用两步法的情况下根据需要进行聚合。有什么建议吗?

【问题讨论】:

【参考方案1】:

您可以使用条件聚合来简化事情:

SELECT
    ThingName,
    count(ItemNumber) as TotalItems,
    count(case when ItemStatus='Red' then ItemNumber  end) as RedItems,
    count(case when ItemStatus='Blue' then ItemNumber  end) as BlueItems
FROM Things
GROUP BY ThingName;

因此,不要使用使用CASE 表达式来获取Total、Red、Blue 项的计数的子查询,而是在聚合函数COUNT直接使用CASE 表达式在这种情况下。

Demo here

【讨论】:

【参考方案2】:

也可以使用sum:

SELECT
      ThingName,
      COUNT(*) as TotalItems,
      SUM(CASE ItemStatus WHEN 'Red' THEN 1 ELSE 0 END) AS RedItems,
      SUM(CASE ItemStatus WHEN 'Blue' THEN 1 ELSE 0 END) AS BlueItems
FROM Things
GROUP BY ThingName;

【讨论】:

以上是关于多列条件聚合的主要内容,如果未能解决你的问题,请参考以下文章

基于多列信息的数据框的条件转换、聚合/分组

在 Python/Pandas 中执行不同操作的多列有条件地聚合分组数据

获取熊猫 groupby 对象中多列的最大聚合

Pyspark - 多列聚合

多列上的多个聚合

基于两列或多列的 Spark DataFrame 聚合