我目前使用以下查询来获取按天分组的数据:
SELECT DATE(from_unixtime(timestampcolumn)) as date, COUNT(*)
FROM db.table
WHERE timestampcolumn BETWEEN :startTime AND :endTime
GROUP BY DATE(from_unixtime(timestampcolumn))
ORDER BY timestampcolumn
DATE()
函数返回字符串YYYY-MM-DD
,因此上述查询很简单,适用于按天分组数据,但如何修改它以返回按每周分组的数据?
回应乔纳森的回答:
我尝试在SQL Fiddle中创建一个示例,但DATE()
SQL函数由于某种原因在SQL Fiddle中不起作用(它在SQL Fiddle中不起作用,但它在我的生活和wamp上都有效)服务器)。
所以这里有一个例子,你可以试试,如果你想:
SETUP:
CREATE TABLE example(id INT NOT NULL AUTO_INCREMENT, PRIMARY KEY(id), timestamp INT, data INT);
INSERT INTO example (timestamp, data) VALUES (1355400000, 1);
INSERT INTO example (timestamp, data) VALUES (1355659200, 1);
INSERT INTO example (timestamp, data) VALUES (1357694861, 1);
INSERT INTO example (timestamp, data) VALUES (1355918400, 1);
INSERT INTO example (timestamp, data) VALUES (1356955200, 1);
INSERT INTO example (timestamp, data) VALUES (1358510400, 1);
INSERT INTO example (timestamp, data) VALUES (1358769600, 1);
INSERT INTO example (timestamp, data) VALUES (1358769600, 1);
INSERT INTO example (timestamp, data) VALUES (1371824368, 1);
INSERT INTO example (timestamp, data) VALUES (1371833476, 1);
INSERT INTO example (timestamp, data) VALUES (1371840324, 1);
INSERT INTO example (timestamp, data) VALUES (1371850523, 1);
INSERT INTO example (timestamp, data) VALUES (1371863191, 1);
INSERT INTO example (timestamp, data) VALUES (1371865401, 1);
INSERT INTO example (timestamp, data) VALUES (1371872379, 1);
INSERT INTO example (timestamp, data) VALUES (1372006190, 1);
INSERT INTO example (timestamp, data) VALUES (1372051945, 1);
INSERT INTO example (timestamp, data) VALUES (1372189402, 1);
INSERT INTO example (timestamp, data) VALUES (1372207830, 1);
INSERT INTO example (timestamp, data) VALUES (1372229733, 1);
INSERT INTO example (timestamp, data) VALUES (1372350338, 1);
INSERT INTO example (timestamp, data) VALUES (1372358259, 1);
QUERY:
SELECT DATE(from_unixtime(timestamp)) as date, COUNT(*)
FROM example
WHERE timestamp BETWEEN 0 AND 9999999999999999999999999999999
GROUP BY DATE(from_unixtime(timestamp))
ORDER BY timestamp
输出:
2012-12-13 1
2012-12-16 1
2012-12-19 1
2012-12-31 1
2013-01-08 1
2013-01-18 1
2013-01-21 2
2013-06-21 7
2013-06-23 1
2013-06-24 1
2013-06-25 2
2013-06-26 1
2013-06-27 2
现在,将时间戳除以(7 * 24 * 3600)
。
QUERY:
SELECT DATE(from_unixtime(timestamp / (7 * 24 * 3600))) as date, COUNT(*)
FROM example
WHERE timestamp BETWEEN 0 AND 9999999999999999999999999999999
GROUP BY DATE(from_unixtime(timestamp / (7 * 24 * 3600)))
ORDER BY timestamp
输出:
1969-12-31 22
答案 0 :(得分:3)
一个基本想法应该是按时间戳的整数值除以一周中的秒数来分组:timestampcolumn / (7 * 24 * 3600)
然后您需要考虑边缘效应和时区:
您可以通过在分割之前向时间戳列添加适当的值来处理这些问题。最后一个转折:一些系统可能会弥补闰秒。 POSIX没有。你必须决定这对你是否重要。
另一个需要考虑的选择是,是否有办法将日期格式化为周值(例如,2013年第23周的2013-W23等ISO 8601表示法)。然后,您可以按该字符串进行分组。
这就是我的意思:
SELECT timestamp / (7 * 24 * 3600) AS weekno, COUNT(*)
FROM example
WHERE timestamp BETWEEN 0 AND 9999999999999999999999999999999
GROUP BY timestamp / (7 * 24 * 3600)
ORDER BY weekno
您可能可以使用GROUP BY weekno
,或者您可能需要ORDER BY timestamp / (7 * 24 * 3600)
,但您可以制作周数。如果您还需要生成日期,则使用:
SELECT timestamp / (7 * 24 * 3600) AS weekno,
DATE(FROM_UNIXTIME((7 * 24 * 3600) * INT(timestamp / (7 * 24 * 3600))))) AS weekstart,
COUNT(*)
FROM example
WHERE timestamp BETWEEN 0 AND 9999999999999999999999999999999
GROUP BY timestamp / (7 * 24 * 3600)
ORDER BY weekno
除非您认为一周的第一天并不总是在数据中表示,否则您可能还会MIN(DATE(FROM_UNIXTIME(timestamp)))
使用weekstart
。
答案 1 :(得分:0)
您是否只能使用原始查询并使用WEEK函数而不是DAY()?
GROUP BY WEEK(from_unixtime(timestampcolumn))
答案 2 :(得分:0)
这是一个基于上述建议的经过测试的干净解决方案:
SELECT WEEK(from_unixtime(timestamp)) AS week_no,
date(from_unixtime(timestamp)) as week_start,
COUNT(*) as row_count
FROM api_tracker
GROUP BY WEEK(from_unixtime(timestamp))
ORDER BY week_no DESC
SQL响应: