使用子查询
解决此问题的一种方法是使用subqueries。 LEFT JOIN 为右表中的每个匹配项创建一个新的“结果”,因此使用两个 LEFT JOIN 会创建比您想要的更多的 ROWS。你可以只选择你想要的值,但这可能很慢:
SELECT ta.id,
(SELECT SUM(total_sold) as total_sold
FROM table_b
WHERE date_sold BETWEEN ADDDATE(NOW(), INTERVAL -1 WEEK) AND NOW()
AND id=ta.id) as total_sold_this_week,
(SELECT SUM(total_sold) as total_sold
FROM table_b
WHERE date_sold BETWEEN ADDDATE(NOW(), INTERVAL -1 MONTH) AND NOW()
AND id = ta.id) as total_sold_this_month
FROM table_a ta;
结果:
+----+------+------------------ -----+
|编号 | total_sold_this_week | total_sold_this_month |
+----+----------+---------- --+
| 1 | 3 | 7 |
| 2 | 4 | 4 |
| 3 |空 |空 |
+----+----------+---------- --+
3 行一组(0.04 秒)
使用 SUM(CASE ...)
此方法不使用子查询(在较大的数据集上可能会更快)。我们想将 table_a 和 table_b 连接在一起一次,使用我们的“最大”日期范围,然后使用基于 CASE 的 SUM() 来计算“较小的范围”。
SELECT ta.*,
SUM(total_sold) as total_sold_last_month,
SUM(CASE
WHEN date_sold BETWEEN NOW() - INTERVAL 1 WEEK AND NOW()
THEN total_sold
ELSE 0
END) as total_sold_last_week
FROM table_a AS ta
LEFT JOIN table_b AS tb
ON ta.id=tb.id AND tb.date_sold BETWEEN ADDDATE(NOW(),INTERVAL -1 MONTH) AND NOW()
GROUP BY ta.id;
这将返回与子查询示例几乎相同的结果集:
+----+------------------------+----------------- -----+
|编号 | total_sold_last_month | total_sold_last_week |
+----+------------------------+-------- --+
| 1 | 7 | 3 |
| 2 | 4 | 4 |
| 3 |空 | 0 |
+----+------------------------+-------- --+
3 行一组(0.00 秒)
唯一的区别是0 而不是NULL。您可以使用此方法汇总任意数量的日期范围,但最好将返回的行限制在 ON 子句中的最大范围内。
只是为了展示它是如何工作的:删除 GROUP BY 和 SUM() 调用,并将 date_sold 添加到 SELECT 会返回:
+----+------------+-----------+---- ------------------+
|编号 |售出日期 | total_sold_last_month | total_sold_last_week |
+----+------------+-----------+-------- ---------------+
| 1 | 2010-04-30 | 2 | 2 |
| 1 | 2010-04-24 | 2 | 0 |
| 1 | 2010-04-24 | 2 | 0 |
| 1 | 2010-05-03 | 1 | 1 |
| 2 | 2010-05-03 | 4 | 4 |
| 3 |空 |空 | 0 |
+----+------------+-----------+-------- ---------------+
一组 6 行(0.00 秒)
现在,当您 GROUP BY id 和 SUM() 这两个 total_sold 列时,您就有了结果!
老建议
在混合使用两个不同的日期范围之前,您可以使用GROUP BY 使用 table1 上的表 ID 进行分组,并使用 SUM() 聚合函数将返回的行相加。
SELECT ta.id, SUM(tb.total_sold) as total_sold_this_week
FROM table_a as ta
LEFT JOIN table_b as tb
ON ta.id=tb.id AND tb.date_sold BETWEEN ADDDATE(NOW(),INTERVAL -3 WEEK) AND NOW()
GROUP BY ta.id
+----+----------+
|编号 | total_sold_this_week |
+----+----------+
| 1 | 7 |
| 2 | 4 |
| 3 |空 |
+----+----------+
3 行一组(0.00 秒)
测试数据
NOW() 是 2010-05-03
mysql> select * from table_a;从 table_b 中选择 *;
+----+
|编号 |
+----+
| 1 |
| 2 |
| 3 |
+----+
3 行一组(0.00 秒)
+----+------------+------------+
|编号 |售出日期 |已售出 |
+----+------------+------------+
| 1 | 2010-04-24 | 2 |
| 1 | 2010-04-24 | 2 |
| 1 | 2010-04-30 | 2 |
| 1 | 2010-05-03 | 1 |
| 2 | 2010-05-03 | 4 |
+----+------------+------------+
5 行一组(0.00 秒)