SQL多表UNION分组查询获取各Group对应最高Time值单条结果的实现
问题根源
现有SQL先对PerformanceOpc、StoppageOpc两张表分别按[Group]+ArticleNumber维度聚合最大时间后再做UNION合并,合并后没有按[Group]维度做单条过滤,因此同一个分组下会保留多个不同ArticleNumber对应的时间记录,不符合每个Group仅返回最高Time对应单条结果的要求。
调整实现方案
先将两张表的聚合结果合并为统一数据集,再通过窗口函数按[Group]分区、Time倒序排序,仅保留每个分组下排名第1的记录即可,完整可运行SQL如下:
WITH MergedTimeData AS ( -- 合并两个表的时间聚合结果,替换原UNION为UNION ALL减少去重性能开销 SELECT [Group], ArticleNumber, MAX(TimeTrue) AS Time FROM PerformanceOpc (NOLOCK) WHERE [Group] IN ('Pack2', '70521-030') GROUP BY [Group], ArticleNumber UNION ALL SELECT [Group], ArticleNumber, MAX(StopTime) AS Time FROM StoppageOpc (NOLOCK) WHERE [Group] IN ('Pack2', '70521-030') GROUP BY [Group], ArticleNumber ), GroupTimeRank AS ( -- 按Group分区,按时间倒序生成行号 SELECT [Group], ArticleNumber, Time, ROW_NUMBER() OVER (PARTITION BY [Group] ORDER BY Time DESC) AS time_sort_rank FROM MergedTimeData ) -- 仅取每个Group下时间最高的1条记录 SELECT [Group], ArticleNumber, Time FROM GroupTimeRank WHERE time_sort_rank = 1 ORDER BY Time DESC
补充说明
- 代码中用
IN替代原多条件OR判断,简化过滤条件写法 - 若需保留同一Group下并列最高时间的所有记录,可将窗口函数
ROW_NUMBER()替换为RANK() - 若数据库版本不支持CTE语法,可将窗口函数逻辑嵌套在子查询中实现相同效果
内容的提问来源于stack exchange,提问作者lukas jarmolowski
相关产品推荐
相关产品推荐

