MySQL-选择一周的开始和结束以及一列的平均值(逐周)

时间:2017-05-26 10:30:10

标签: mysql

我试图在过去的6周内逐周获得player_count列的平均值。但问题是我还想要与特定平均值相对应的星期日的开始和结束。

我尝试过:

SELECT AVG(player_count) as average, 
  updated_at, 
  updated_at + INTERVAL WEEKDAY(updated_at) + 7 DAY as EndDate 
FROM `gtan_servers` 
WHERE server_short_name = 'FiveRP' 
GROUP BY WEEK(updated_at) 
ORDER BY updated_at DESC 
LIMIT 6

updated_at列旨在作为一周的开始,EndDate将被视为提供播放器计数的特定平均值的一周结束。

但是这个查询在周日期间无法正常工作。我可以获取平均值,但是周日期没有正确获取。任何帮助都将受到高度赞赏。

1 个答案:

答案 0 :(得分:1)

您需要一个截断任意日期的表达式,直到发生它的一周的第一天。也就是说,如果你给它2017-05-21

,它会返回2017-05-24(星期日)

这个表达式可以做到这一点,假设您的星期几是星期几开始的。 Here's an explanation.

    FROM_DAYS(TO_DAYS(datestamp) -MOD(TO_DAYS(datestamp) -1, 7))

然后你需要将它用作GROUP BY表达式和WHERE表达式。

SELECT AVG(player_count) as average, 
  FROM_DAYS(TO_DAYS(updated_at) -MOD(TO_DAYS(updated_at) -1, 7)) week_beginning, 
  FROM_DAYS(TO_DAYS(updated_at) -MOD(TO_DAYS(updated_at) -1, 7)) + INTERVAL 6 DAY week_ending 
FROM `gtan_servers` 
WHERE server_short_name = 'FiveRP' 
  AND updated_at >= FROM_DAYS(TO_DAYS(NOW()) -MOD(TO_DAYS(NOW()) -1, 7)) - INTERVAL 6 WEEK
GROUP BY FROM_DAYS(TO_DAYS(updated_at) -MOD(TO_DAYS(updated_at) -1, 7)) 
ORDER BY 2 DESC 
LIMIT 6

WHERE会自动过滤出表格中过于陈旧的记录。

这个查询有点重复,但效果很好。

你可以像这样创建一个存储的函数:

DELIMITER $$
DROP FUNCTION IF EXISTS TRUNC_SUNDAY$$
CREATE
  FUNCTION TRUNC_SUNDAY(datestamp DATETIME)
  RETURNS DATE DETERMINISTIC NO SQL
  COMMENT 'returns preceding Sunday'
  RETURN FROM_DAYS(TO_DAYS(datestamp) -MOD(TO_DAYS(datestamp) -1, 7))$$
DELIMITER ;

然后您的查询变得更具可读性:

SELECT AVG(player_count) as average, 
  TRUNC_SUNDAY(updated_at) week_beginning, 
  TRUNC_SUNDAY(updated_at) + INTERVAL 6 DAY week_ending 
FROM `gtan_servers` 
WHERE server_short_name = 'FiveRP' 
  AND updated_at >= TRUNC_SUNDAY(NOW()) - INTERVAL 6 WEEK
GROUP BY TRUNC_SUNDAY(updated_at) 
ORDER BY TRUNC_SUNDAY(updated_at) DESC 
LIMIT 6

如果您的周数从周一开始,请将-1更改为-2