计算具有特定列的所有行并按周分组

时间:2012-06-14 15:21:15

标签: mysql sql

我现在已经尝试了一段时间来创建一个查询,该查询将计算每天包含具有特定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

以便日期时间戳是第一列,第二列是每周的行数。

2 个答案:

答案 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))