如何通过单条查询从两张表统计月度订单金额及商品小计
单条SQL实现月度订单金额与商品小计统计
咱们先来明确核心需求:用一条SQL语句,基于Orders和Items两张表,按月份聚合统计两个关键指标——月度订单总金额和月度商品小计总额。
先回顾下两张表的结构与数据
Orders表
| id | service_fee_cents | grand_total_cents | created_at |
|---|---|---|---|
| 1 | 1400 | 10000 | Jan 21 2018 |
| 2 | 1000 | 10000 | Feb 16 2018 |
| 3 | 500 | 10000 | March 21 2018 |
| 4 | 500 | 10000 | March 20 2018 |
Items表(补充你给出的不完整数据,方便示例)
| id | order_id | title | price_cents | quantity |
|---|---|---|---|---|
| 1 | 1 | lorem | 2000 | 2 |
| 2 | 1 | ipsum | 2030 | 1 |
| 3 | 2 | dolor | 3000 | 2 |
不同数据库的SQL实现
因为不同数据库的日期处理函数略有差异,我分别给出常用的两种版本:
PostgreSQL/Redshift 版本
SELECT DATE_TRUNC('month', o.created_at) AS order_month, SUM(o.grand_total_cents) AS monthly_order_total_cents, SUM(i.price_cents * i.quantity) AS monthly_item_subtotal_cents FROM Orders o LEFT JOIN Items i ON o.id = i.order_id GROUP BY DATE_TRUNC('month', o.created_at) ORDER BY order_month;
MySQL 版本
SELECT DATE_FORMAT(o.created_at, '%Y-%m') AS order_month, SUM(o.grand_total_cents) AS monthly_order_total_cents, SUM(i.price_cents * i.quantity) AS monthly_item_subtotal_cents FROM Orders o LEFT JOIN Items i ON o.id = i.order_id GROUP BY DATE_FORMAT(o.created_at, '%Y-%m') ORDER BY order_month;
关键逻辑解释
LEFT JOIN:用左连接而非内连接,是为了避免漏掉那些没有关联商品的订单(虽然你的示例里没有这种情况,但实际业务中可能存在),保证订单金额的统计完整性。- 日期截断/格式化:
DATE_TRUNC(PG系)或DATE_FORMAT(MySQL)的作用是把created_at转换成月份维度,让同一个月的所有订单能被归为一组统计。 - 聚合计算:
SUM(o.grand_total_cents)直接累加每个月所有订单的总金额;SUM(i.price_cents * i.quantity)则是先计算单个商品的小计(单价×数量),再累加整个月的所有商品小计。
GROUP BY+ORDER BY:按月份分组确保统计结果是月度汇总,排序则让结果按时间顺序展示,更直观。
基于你提供数据的示例输出
| order_month | monthly_order_total_cents | monthly_item_subtotal_cents |
|---|---|---|
| 2018-01-01 | 10000 | 6030 |
| 2018-02-01 | 10000 | 6000 |
| 2018-03-01 | 20000 | 0 |
内容的提问来源于stack exchange,提问作者Amin Shah Gilani
相关产品推荐
相关产品推荐

