我试图在过去的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
将被视为提供播放器计数的特定平均值的一周结束。
但是这个查询在周日期间无法正常工作。我可以获取平均值,但是周日期没有正确获取。任何帮助都将受到高度赞赏。
答案 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
。