DB2查询去重:保留每个账户各模板最新时间戳记录
DB2查询去重:保留每个账户-模板的最新时间戳记录
你的原SQL存在两个关键问题:
- 子查询中
GROUP BY account, template, ts会把每个不同时间戳的记录单独分组,导致MAX(ts)失去意义(每个分组的ts本身就是唯一值,最大值就是自己) DISTINCT(account, template, max(ts))的写法不符合DB2语法,且GROUP BY已经保证了account+template的唯一性,DISTINCT是多余的
以下是两种正确的实现方案:
方案1:子查询关联法
先通过分组获取每个账户-模板组合的最新时间戳,再关联原表提取完整记录:
SELECT a.account, a.template, a.tracking_no, a.ts FROM table1 a JOIN ( -- 先拿到每个account+template对应的最大时间戳 SELECT account, template, MAX(ts) AS max_ts FROM table1 WHERE template IN (<TEMPLATE LIST>) -- 替换为实际模板值,比如('TPL1','TPL2','TPL3','TPL4') GROUP BY account, template ) b ON a.account = b.account AND a.template = b.template AND a.ts = b.max_ts WITH UR;
如果同一个账户-模板下有多条记录时间戳相同且都是最新,该方案会保留所有这些记录。
方案2:窗口函数法(推荐大数据量场景)
使用ROW_NUMBER()窗口函数直接标记每个分组的最新记录,性能更优:
SELECT account, template, tracking_no, ts FROM ( SELECT account, template, tracking_no, ts, -- 按account+template分组,按ts倒序排序,给每条记录编号 ROW_NUMBER() OVER (PARTITION BY account, template ORDER BY ts DESC) AS rn FROM table1 WHERE template IN (<TEMPLATE LIST>) ) t WHERE rn = 1 -- 只取每个分组的第一条(最新记录) WITH UR;
如果存在同账户-模板下多条记录时间戳相同的情况,该方案会仅保留其中一条(若需指定规则,可在ORDER BY ts DESC后追加其他字段,比如ORDER BY ts DESC, tracking_no ASC)。
性能优化建议
针对200万条数据的场景,建议创建复合索引:CREATE INDEX idx_table1_acc_tpl_ts ON table1(account, template, ts DESC);,能大幅提升分组和关联的效率。
内容的提问来源于stack exchange,提问作者Patricia Flickner
相关产品推荐
相关产品推荐

