如何通过MySQL计算具有日期间隔的统计信息

时间:2014-07-03 09:21:17

标签: php mysql sql

我想计算一些按日期和动态间隔(周,月,年)排序的统计数据(带有MySQL后端)。 这是一个小例子:

Mysql表: tracker_click

| ID   | SITE_ID | CREATED_AT          |
| ---- |---------| --------------------|
| 153  | 2       | 2013-07-22 15:43:25 |
| 154  | 2       | 2013-07-25 16:45:46 |
| 2501 | 2       | 2013-09-15 17:45:48 |

我希望通过一个查询获得上个月SITE_ID的总点击次数 去年同月也一样。

上个月按周计算的一个例子是:

| click number   | SITE_ID | BEGIN_DATE           | END_DATE            |
|----------------|---------|----------------------|---------------------|
| 25             |    2    |  2013-07-01 00:00:00 | 2013-07-08 00:00:00 |
| 19             |    2    |  2013-08-09 00:00:00 | 2013-08-16 00:00:00 |
| 53             |    2    |  2013-0717- 00:00:00 | 2013-08-24 00:00:00 |

我不知道是否有一个解决方案只需一个查询而不需要任何其他进程即可获得exaclty这个数组。

谢谢

2 个答案:

答案 0 :(得分:2)

这可以为您提供上个月(即最近4周)的计数,包括每个站点ID的计数为0的周数。如果您有一个站点表来从中获取站点ID,则意味着可以使用简单的交叉连接替换到子查询的交叉连接。

这会生成一个从0到5的数字范围,并从当前日期减去该周数,格式化为结果周的星期日和星期六,并检查结果周是当前日期和当前日期减去1个月(这样做而不是仅减去4周以应对可变长度的月份)。

SELECT Weeks.aWeek_start, Weeks.aWeek_end, all_site_id.site_id, COUNT(tracker_click.id)
FROM
(
    SELECT STR_TO_DATE(DATE_FORMAT(DATE_SUB(NOW(), INTERVAL units.i WEEK), '%Y%U Sunday 00:00:00'), '%X%V %W %H:%i:%s') AS aWeek_start,
            STR_TO_DATE(DATE_FORMAT(DATE_SUB(NOW(), INTERVAL units.i WEEK), '%Y%U Saturday 23:59:59'), '%X%V %W %H:%i:%s') AS aWeek_end
    FROM (SELECT 0 i UNION SELECT 1 UNION SELECT 2 UNION SELECT 3 UNION SELECT 4 UNION SELECT 5)units
    WHERE DATE_FORMAT(DATE_SUB(NOW(), INTERVAL units.i WEEK), '%Y%U') BETWEEN DATE_FORMAT(DATE_SUB(NOW(), INTERVAL 1 MONTH), '%Y%U') AND DATE_FORMAT(NOW(), '%Y%U')
) Weeks
CROSS JOIN
(
    SELECT DISTINCT site_id
    FROM tracker_click
) AS all_site_id
LEFT OUTER JOIN tracker_click
ON tracker_click.CREATED_AT BETWEEN Weeks.aWeek_start AND Weeks.aWeek_end
AND tracker_click.site_id = all_site_id.site_id
GROUP BY Weeks.aWeek_start, Weeks.aWeek_end, all_site_id.site_id

可以在一年中的几个月进行类似的查询

SELECT Months.aMonth_start, Months.aMonth_end, all_site_id.site_id, COUNT(tracker_click.id)
FROM
(
    SELECT DATE_FORMAT(DATE_SUB(NOW(), INTERVAL units.i MONTH), '%Y/%m/01 00:00:00') AS aMonth_start,
            DATE_FORMAT(LAST_DAY(DATE_SUB(NOW(), INTERVAL units.i MONTH)), '%Y/%m/%d 23:59:59') AS aMonth_end
    FROM (SELECT 0 i UNION SELECT 1 UNION SELECT 2 UNION SELECT 3 UNION SELECT 4 UNION SELECT 5 UNION SELECT 6 UNION SELECT 7 UNION SELECT 8 UNION SELECT 9 UNION SELECT 10 UNION SELECT 11)units
) Months
CROSS JOIN
(
    SELECT DISTINCT site_id
    FROM tracker_click
) AS all_site_id
LEFT OUTER JOIN tracker_click
ON tracker_click.CREATED_AT BETWEEN Months.aMonth_start AND Months.aMonth_end
AND tracker_click.site_id = all_site_id.site_id
GROUP BY Months.aMonth_start, Months.aMonth_end, all_site_id.site_id

答案 1 :(得分:0)

SELECT count(*), site_id, extract(WEEK from created_at) as start_date, 
date_add(extract(WEEK from created_at), 1, week) as end_date
FROM click_tracker
GROUP BY site_id, extract(WEEK from created_at)

并且您可以添加where子句以额外过滤结果。