Nitpick:DATE 是一个糟糕的列名选择,因为它是一个保留的 SQL 字。
这里有四个层次的逻辑。
首先,您需要有工作逻辑来确定每天在哪一周。
其次,您需要选择正确的DATE值范围。
第三,你需要把GROUP BY的逻辑弄对。
第四,您需要将结果集转为本周和上周的同一行。这种旋转应该是另一个问题的主题。
首先,此表达式会将任何DATETIME 值转换为前一个星期日。
FROM_DAYS(TO_DAYS(value) -MOD(TO_DAYS(value) -1, 7))
其次,这里是你需要选择的两周(上周和本周)
WHERE `DATE` >= FROM_DAYS(TO_DAYS(NOW()) -MOD(TO_DAYS(NOW()) -1, 7)) - INTERVAL 7 DAY
AND `DATE` < FROM_DAYS(TO_DAYS(NOW()) -MOD(TO_DAYS(NOW()) -1, 7)) + INTERVAL 7 DAY
这将获取从上周日之前的周日开始到本周日之后的周日之前结束的日期范围,为期两周。
第三,你需要正确分组。在您的架构中,按周和按国家/地区分组。它会是这样的:
SELECT SUM(`GP`) AS GP,
`Country`,
FROM_DAYS(TO_DAYS(`DATE`) -MOD(`DATE`) -1, 7)) AS week_beginning
FROM `Finance`
WHERE `DATE` >= FROM_DAYS(TO_DAYS(NOW()) -MOD(TO_DAYS(NOW()) -1, 7)) - INTERVAL 7 DAY
AND `DATE` < FROM_DAYS(TO_DAYS(NOW()) -MOD(TO_DAYS(NOW()) -1, 7)) + INTERVAL 7 DAY
GROUP BY `Country`, FROM_DAYS(TO_DAYS(`DATE`) -MOD(`DATE`) -1, 7))
ORDER BY `Country`, FROM_DAYS(TO_DAYS(`DATE`) -MOD(`DATE`) -1, 7))
这将为每个国家/地区提供两行,一行用于一周前的 week_beginning,另一行用于当前一周。这可以为您解决问题。如果没有,您可以旋转此查询的结果以按照您想要的方式排列行。那应该是另一个问题的主题。
最后,如果你可以在你的 MySQL 实例中定义存储函数,你应该定义函数 TRUNC_SUNDAY。然后您可以像这样编写更具可读性的查询:
SELECT SUM(`GP`) AS GP,
`Country`,
TRUNC_SUNDAY(`DATE`) AS week_beginning
FROM `Finance`
WHERE `DATE` >= TRUNC_SUNDAY(NOW()) - INTERVAL 7 DAY
AND `DATE` < TRUNC_SUNDAY(NOW()) + INTERVAL 7 DAY
GROUP BY `Country`, TRUNC_SUNDAY(`DATE`)
ORDER BY `Country`, TRUNC_SUNDAY(`DATE`)
这是定义您需要的存储 TRUNC_SUNDAY 函数的 SQL 代码:
DELIMITER $$
DROP FUNCTION IF EXISTS `TRUNC_SUNDAY`$$
CREATE FUNCTION `TRUNC_SUNDAY`(datestamp DATETIME)
RETURNS DATE
NO SQL
DETERMINISTIC
COMMENT 'returns preceding Sunday'
RETURN FROM_DAYS(TO_DAYS(datestamp) -MOD(TO_DAYS(datestamp) -1, 7))$$
DELIMITER ;
您可以在此处找到该技术的详细说明,包括 TRUNC_MONDAY 函数。如果您的工作日定义为从星期一开始而不是星期日,您将需要 TRUNC_MONDAY 函数。 http://www.plumislandmedia.net/mysql/sql-reporting-time-intervals/