!已修改!
我有一个表(mySQL 5.0.x),其中包含日期范围的值。
| id | link_id | type_id | value | start | end |
====================================================
| 1 | 1 | 1 | 10 | 201111 | 201202 |
| 2 | 1 | 2 | 20 | 201110 | 201201 |
| 3 | 1 | 1 | 100 | 201202 | 201202 |
| 4 | 2 | 1 | 40 | 201202 | 201203 |
,其中
诀窍在于我需要按月提供每个类型的总价值和给定时期的链接。所以对于201201 - 201202的范围,结果应该是这样的:
| period | link_id | type_id | value |
======================================
| 201201 | 1 | 1 | 10 |
| 201202 | 1 | 1 | 110 |
| 201201 | 1 | 2 | 20 |
| 201201 | 2 | NULL | NULL |
| 201202 | 2 | 1 | 40 |
我可以使用PHP将这样的信息放入数据库,但是有一些缺点。我有数百个link_id,很多type_id,开始和结束日期之间的平均差异是30个月所以我会有很多行。
答案 0 :(得分:0)
这是一种方法。我已经放入了$startMonth
和$endMonth
,所以你可以看到他们是如何玩的。(我有这种琐碎的感觉,这可以简化,但它当前逃脱了我):
SET @MONTH:=$startMonth-1;
SELECT month, link_id, type_id, SUM(value) AS value
FROM (SELECT @MONTH:=@MONTH+1 as month
FROM foo f
LIMIT $endMonth-$startMonth+1) a
LEFT JOIN foo f
ON a.month >= f.start AND a.month <= f.end
GROUP BY link_id, type_id, a.month;
它的工作方式:假设你有一个表a
:
+-------+
| month |
+-------+
|201201 |
|201202 |
+-------+
然后你想要的查询更容易解决:
SELECT month, link_id, type_id, SUM(value) AS value
FROM a
LEFT JOIN foo
ON a.month >= f.start AND a.month <= f.end
GROUP BY link_id, type_id, a.month;
即通过确保a
介于开始和结束时段之间,您将foo
加入month
,然后您只需总结值,按月分组,链接ID,并输入id。
所以问题是如何生成包含a
到$startMonth
的数字的表$endMonth
。因此:
SET @MONTH:=201200;
SELECT @MONTH:=@MONTH+1 AS month
FROM foo
LIMIT 2;
这会从201201
和2行(即最多201202
)提供一个数字表格。在这个查询中,FROM foo
是虚拟的 - 没有真正使用过。