MySQL:每月为包含日期范围的数据创建一行

时间:2012-02-09 10:08:13

标签: mysql grouping date-range

!已修改!

我有一个表(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 |

,其中

  • id 是记录的ID
  • link_id 用于将数据链接到其他表格
  • type_id 用于确定其他表格中的值的类型
  • 是数值
  • 开始结束定义范围(年份和月份的实际日期或整数)

诀窍在于我需要按月提供每个类型的总价值和给定时期的链接。所以对于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个月所以我会有很多行。

1 个答案:

答案 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是虚拟的 - 没有真正使用过。