分组和求和,使用非聚合标准来确定字段选择

Posted

技术标签:

【中文标题】分组和求和,使用非聚合标准来确定字段选择【英文标题】:Grouping and summing, using non-aggregate critera to determine field selection 【发布时间】:2020-07-20 08:40:03 【问题描述】:

[MS SQL Server 2005 上的 T-SQL]

我正在尝试对 SQL 表中的行进行分组,但对如何选择某些列选项有要求,而不仅仅是基于通常的聚合函数。所以例如我有这张桌子:

HeaderID    mold_no     pipe_no cp_date         class total_pcs total_pss run_time
----------- ----------- ------- --------------- ----- --------- --------- ---------
113149      1603        A22     2019-10-17      35    216       1         9.08
113320      1603        A22     2019-10-17      35    1         0         0.00

我想按mold_nopipe_nocp_dateclass 分组。

但是,我想使用与run_time 的最大值相对应的HeaderID 值。

所以我现在有

select MIN(HeaderID) HeaderID, MAX(mold_no) mold_no, MAX(pipe_no) pipe_no, MAX(cp_date) cp_date,
    MAX(machine) machine, MAX(class) class, SUM(total_pcs) total_pcs, SUM(total_pss) total_pss 
from MyTable
group by cp_date, machine, mold_no, pipe_no, class 

但这当然行不通,因为我不能保证编号最小的 HeaderID 值总是正确的。

如何根据最大的run_time 值选择所需的HeaderID 值?

【问题讨论】:

【参考方案1】:

这不是聚合;这是过滤。使用相关子查询:

select t.*
from t
where t.run_time = (select max(t2.run_time)
                    from t t2
                    where t2.mold_no = t.mold_no and
                          t2.pipe_no = t.pipe_no and
                          t2.cp_date = t.cp_date and
                          t2.class = t.class
                  );

【讨论】:

【参考方案2】:

您可以使用CTE,在run_time 值上递减计算ROW_NUMBER(),使用窗口函数进行聚合,然后选择带有ROW_NUMBER() = 1 的行(因为这将具有最大run_time 值) :

WITH CTE AS (
   SELECT HeaderID, mold_no, pipe_no, cp_date, class,
          SUM(total_pcs) OVER (PARTITION BY mold_no, pipe_no, cp_date, class) AS total_pcs,
          SUM(total_pss) OVER (PARTITION BY mold_no, pipe_no, cp_date, class) AS total_pss,
          run_time,
          ROW_NUMBER() OVER (PARTITION BY mold_no, pipe_no, cp_date, class ORDER BY run_time DESC) AS rn
    FROM data
)
SELECT HeaderID, mold_no, pipe_no, cp_date, class, total_pcs, total_pss, run_time
FROM CTE
WHERE rn = 1

输出:

HeaderID    mold_no     pipe_no     cp_date     class   total_pcs   total_pss   run_time
113149      1603        A22         2019-10-17  35      217         1           9.08

Demo on SQLFiddle

【讨论】:

以上是关于分组和求和,使用非聚合标准来确定字段选择的主要内容,如果未能解决你的问题,请参考以下文章

选择多个字段分组并求和

如何选择 n 列和一个 SUM,同时仅按一些非聚合列分组?

在子选择中创建聚合,而无需将引用的字段添加到分组列表

选择对两列求和并希望将结果用作选择条件的查询 [重复]

如何使用 Django 进行分组和聚合

Mongodb对来自聚合方面的两个相似数据数组进行分组和求和