SQL分组求和时如何根据组内最早日期条件排除不符合的分组
SQL实现方案
核心逻辑非常直接:按name分组后,同时计算分组金额总和、分组内最早日期,最后过滤掉最早日期距当前日期不足3个月的分组即可。
前置注意项
你的样例数据中dollars字段携带$前缀,属于字符串类型,直接调用SUM会触发类型错误,需要先去除$转为数值计算,最终输出时再拼接回$前缀即可。如果实际业务中dollars已经是数值类型,跳过这步转换逻辑。
通用聚合写法(兼容主流SQL数据库)
这是性能最好、最简洁的写法,适用于MySQL、PostgreSQL、BigQuery等绝大多数支持标准SQL的引擎:
SELECT name, MAX(date) AS date, -- 对齐样例输出,取分组内最新日期 CONCAT('$', SUM(REPLACE(dollars, '$', '') + 0)) AS dollars FROM temp_table_a GROUP BY name -- 过滤条件:分组最早记录的日期早于「当前日期往前推3个月」的时间点 HAVING MIN(date) < -- 不同数据库的日期计算函数略有差异,按需选择对应写法即可 -- MySQL/MariaDB 用下一行: DATE_SUB(CURDATE(), INTERVAL 3 MONTH) -- PostgreSQL 用下一行: -- CURRENT_DATE - INTERVAL '3 months' -- SQL Server 用下一行: -- DATEADD(month, -3, GETDATE())
逻辑校验(匹配你的样例)
- 分组
name=A的最早记录日期为2022-03-01,距参考日期2022-06-01满3个月,满足保留条件,金额求和后为$1325(注:你给出的样例输出$1375应为笔误,按给出的明细行累加结果为1325) - 分组
name=B的最早记录日期为2022-04-01,距参考日期不足3个月,会被过滤,完全符合你的预期。
可选CTE写法(便于后续扩展逻辑)
如果后续需要增加更多过滤规则、或者关联其他表,可以用CTE先完成聚合计算再过滤,可读性更强:
WITH group_stat AS ( SELECT name, MAX(date) AS latest_date, MIN(date) AS earliest_date, SUM(REPLACE(dollars, '$', '') + 0) AS total_dollars FROM temp_table_a GROUP BY name ) SELECT name, latest_date AS date, CONCAT('$', total_dollars) AS dollars FROM group_stat WHERE earliest_date < DATE_SUB(CURDATE(), INTERVAL 3 MONTH) -- 替换为你所用数据库对应的日期计算函数即可
内容的提问来源于stack exchange,提问作者caroh
相关产品推荐
相关产品推荐

