DB2多表查询:按日期聚合求和并关联历史订单视图
嘿,我来帮你搞定这个SQL查询需求!先把我们手头的信息和目标理清楚:
需求概述
当前日期是2018年5月2日(编码1180502),我们需要从三张表/视图中查询出每个产品的:
- 产品ID、名称
- 去年5月的订单总量(来自OHIST视图)
- 未来3天(D1=5月3日、D2=5月4日、D3=5月5日)每日的订单数量总和
最终按产品ID整理成表格展示。
现有表结构与数据示例
1. ITEMS表(产品列表,ID是主键)
| ID | NAME |
|---|---|
| 10 | Widget10 |
| 11 | Widget11 |
| 12 | Widget12 |
| 13 | Widget13 |
2. ODETAILS表(订单行项目表,无主键)
| OID | ODUE | ITEM_ID | ITEM_QTY |
|---|---|---|---|
| A33 | 1180503 | 10 | 100 |
| A33 | 1180504 | 11 | 215 |
| A34 | 1180505 | 10 | 500 |
| A34 | 1180504 | 11 | 320 |
| A34 | 1180504 | 12 | 450 |
| A34 | 1180505 | 13 | 125 |
3. OHIST视图(展示去年月度订单总量)
| ITEM_ID | M5QTY |
|---|---|
| 10 | 1000 |
| 11 | 1500 |
| 12 | 2251 |
| 13 | 4334 |
日期转换函数说明
这里提供了一个把ODUE编码转换成标准日期的函数:
DATE(concat(concat(concat(substr(char((ODETAILS.ODUE-1000000)+20000000),1,4),'-'), concat(substr(char((ODETAILS.ODUE-1000000)+20000000),5,2), '-')), substr(char((ODETAILS.ODUE-1000000)+20000000),7,2)))
简单说,它能把1180503这种编码转换成2018-05-03这样的可识别日期格式,方便我们按日期筛选订单。
最终SQL查询语句
核心思路是用条件聚合来分别统计未来3天的订单量,同时用LEFT JOIN确保所有产品都能出现在结果里(哪怕某天没有订单):
SELECT i.ID, i.NAME, o.M5QTY, -- 统计5月3日(D1)的订单量 SUM(CASE WHEN DATE(concat(concat(concat(substr(char((od.ODUE-1000000)+20000000),1,4),'-'), concat(substr(char((od.ODUE-1000000)+20000000),5,2), '-')), substr(char((od.ODUE-1000000)+20000000),7,2))) = '2018-05-03' THEN od.ITEM_QTY ELSE NULL END) AS D1, -- 统计5月4日(D2)的订单量 SUM(CASE WHEN DATE(concat(concat(concat(substr(char((od.ODUE-1000000)+20000000),1,4),'-'), concat(substr(char((od.ODUE-1000000)+20000000),5,2), '-')), substr(char((od.ODUE-1000000)+20000000),7,2))) = '2018-05-04' THEN od.ITEM_QTY ELSE NULL END) AS D2, -- 统计5月5日(D3)的订单量 SUM(CASE WHEN DATE(concat(concat(concat(substr(char((od.ODUE-1000000)+20000000),1,4),'-'), concat(substr(char((od.ODUE-1000000)+20000000),5,2), '-')), substr(char((od.ODUE-1000000)+20000000),7,2))) = '2018-05-05' THEN od.ITEM_QTY ELSE NULL END) AS D3 FROM ITEMS i LEFT JOIN OHIST o ON i.ID = o.ITEM_ID LEFT JOIN ODETAILS od ON i.ID = od.ITEM_ID GROUP BY i.ID, i.NAME, o.M5QTY ORDER BY i.ID;
如果希望无订单的日期显示0而非空值,把ELSE NULL改成ELSE 0就行。
预期查询结果
执行上面的SQL后,会得到和你期望完全一致的结果:
| ID | NAME | M5QTY | D1 | D2 | D3 |
|---|---|---|---|---|---|
| 10 | Widget10 | 1000 | 100 | 500 | |
| 11 | Widget11 | 1500 | 535 | ||
| 12 | Widget12 | 2251 | 450 | ||
| 13 | Widget13 | 4334 | 125 |
内容的提问来源于stack exchange,提问作者Tom Sampson
相关产品推荐
相关产品推荐

