如何从算术关系生成SQL查询?解析多表求和表达式生成SQL
如何从算术表达式生成聚合SQL查询(以多表求和场景为例)
我来拆解一下这个需求——从类似 ${table_1} + ${table_2} + ${table_3} 这样的算术表达式生成指定格式的聚合SQL,其实核心是把多个同结构表的数值按时间维度合并求和,下面一步步来:
1. 解析表达式,提取目标表
首先要从表达式里把所有带 ${} 包裹的表名提取出来。比如 ${table_1} + ${table_2} + ${table_3} 里,我们能拿到三个表:table_1、table_2、table_3。这一步需要做简单的字符串解析,把每个 ${} 里的内容抽出来,忽略中间的 + 符号就行。
2. 生成CTE(WITH子句)
为每个提取到的表创建一个临时CTE,只保留我们需要的 date 和 quantity 字段——这样做是为了简化后续的合并逻辑,避免引入无关字段。比如:
TMP_1 AS (SELECT date, quantity FROM table_1), TMP_2 AS (SELECT date, quantity FROM table_2), TMP_3 AS (SELECT date, quantity FROM table_3)
这里的 TMP_n 命名可以按表的顺序递增,方便后续引用。
3. 合并所有CTE的数据
用 UNION ALL 把所有TMP表的数据合并到一起——一定要用UNION ALL,别用UNION!因为UNION会自动去重,会导致我们丢失重复日期的quantity数据,求和结果就不准了。合并后的子查询可以命名为 res_1:
SELECT date, quantity FROM TMP_1 UNION ALL SELECT date, quantity FROM TMP_2 UNION ALL SELECT date, quantity FROM TMP_3
4. 按时间维度聚合求和
最后对合并后的数据按天分组,用 time_bucket('1 day', date)(如果是标准PostgreSQL,换成 date_trunc('day', date) 效果一样)把日期转成天级别的时间桶,然后对quantity求和,再按日期排序:
SELECT time_bucket('1 day', date) AS date, sum(quantity) AS sum FROM res_1 GROUP BY 1 ORDER BY date
完整的SQL示例
把上面的部分拼起来,就是最终的SQL:
WITH TMP_1 AS (SELECT date, quantity FROM table_1), TMP_2 AS (SELECT date, quantity FROM table_2), TMP_3 AS (SELECT date, quantity FROM table_3) SELECT time_bucket('1 day', date) AS date, sum(quantity) AS sum FROM ( SELECT date, quantity FROM TMP_1 UNION ALL SELECT date, quantity FROM TMP_2 UNION ALL SELECT date, quantity FROM TMP_3 ) AS res_1 GROUP BY 1 ORDER BY date ASC;
关键注意事项
- 确保所有目标表的
date和quantity字段类型一致,否则UNION ALL会报错; - 如果表达式里有更多表(比如4个、5个),只需要重复CTE和UNION ALL的步骤即可,逻辑完全通用;
- 若不需要CTE,也可以直接把表的查询写在UNION ALL里,但用CTE会让SQL结构更清晰,可读性更强。
内容的提问来源于stack exchange,提问作者Jeff
相关产品推荐
相关产品推荐

