我试图在过去 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
将作为一周的结束,其中玩家的特定平均值提供计数。
但是关于星期日期的查询不能正常工作。我可以获取平均值,但是没有正确获取周日期。任何帮助将不胜感激。
最佳答案
您需要一个表达式截断一个任意日期到它出现的那一周的第一天。也就是说,如果你给它 2017-05-24
2017-05-21
(星期日)
假设您的周从星期日开始,这个表达式就是这样做的。 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
。
关于MySQL-选择一周的开始和结束以及列的平均值(每周),我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/44199280/