我现在已经尝试了一段时间来创建一个查询,该查询将计算每天包含具有特定id的列的表中的所有行,然后根据UNIX时间戳列将它们分组为每周值。我有一个中等大小的数据集,有3700万行,并且一直在尝试运行以下类型的查询:
SELECT DATE(timestamp), COUNT(*) FROM `table` WHERE ( date(timestamp)
between "YYYY-MM-DD" and "YYYY-MM-DD" and column_group_id=X )
group by week(date(startdate))
虽然我得到了奇怪的结果,但是查询没有正确地对计数进行分组,但是在结果计数列上显示了太大的值(我通过查询非常小的特定数据集来验证值错误。)
如果我按date(startdate)
进行分组,则行数每天匹配,但我想将这些每日行数合并为每周数量。这怎么可能?格式需要数据:
2006-01-01 | 5
2006-01-08 | 10
以便日期时间戳是第一列,第二列是每周的行数。
答案 0 :(得分:1)
您的查询是非确定性的,因此您获得意外结果并不奇怪。我的意思是你可以在相同的数据上运行5次查询,得到5个不同的结果集。这是因为您选择了DATE(timestamp)
但按WEEK(DATE(startdate))
进行分组,因此查询将以 ANY 顺序返回每个开始日期第一行的时间
考虑以下两行(日期格式的时间戳以便于阅读):
TimeStamp StartDate
20120601 20120601
20120701 20120601
您的查询按WEEK(StartDate)
分组,即23,因为两行评估为相同的值,您希望结果有1行,计数为2.
HOWEVER DATE(Timestamp)
同样在选择列表中,由于没有ORDER BY
语句,查询无法知道哪个时间戳返回'20120601'或'20120701'。因此,即使在这个小结果集上,你有50:50的机会获得:
TimeStamp COUNT
20120601 2
和50:50的机会获得
TimeStamp COUNT
20120701 2
如果您向数据集添加更多数据:
TimeStamp StartDate
20120601 20120601
20120701 20120601
20120701 20120701
你可以得到
TimeStamp COUNT
20120601 2
20120701 1
或
TimeStamp COUNT
20120701 2
20120701 1
您可以看到37,000,000行如何很快得到您不期望且无法预测的结果!
修改强>
由于看起来您正试图在结果中获得周末开始,因此您可以使用以下内容逐周开始(将CURRENT_TIMESTAMP替换为您想要的任何列):
SELECT DATE_ADD(CURRENT_TIMESTAMP, INTERVAL 1 - DAYOFWEEK(CURRENT_TIMESTAMP) DAY) AS WeekStart
然后,您也可以按此日期进行分组,以获得每周结果,并避免在您的选择列表中包含不在您的组中的内容的麻烦。
答案 1 :(得分:0)
试试这个
SELECT DATE(timestamp), COUNT(week(date(startdate))) FROM `table` WHERE ( date(timestamp)
between "YYYY-MM-DD" and "YYYY-MM-DD" and column_group_id=X )
group by week(date(startdate))