我需要在一周内显示GP总和的两个计算列,在前一个
中显示另一列我认为我的方式是正确的,但我错过了一些东西
我想让我的结果像这样::
| WEEK | JP | AUS | GB |
| PREV | 22 | 32 | 23 |
| CUR | 12 | 15 | 12 |
我的sql是这个我相信我可能需要转动数据
SELECT
(SUM(`GP`), `gptw`)
FROM
(SELECT
`GP`,
`Country`
FROM
`Finance`
WHERE DATE >= CURDATE() - INTERVAL DAYOFWEEK(CURDATE()) + 6 DAY
AND DATE < CURDATE() - INTERVAL DAYOFWEEK(CURDATE()) - 1 DAY
GROUP BY `Country`) AS lastweeek
INNER JOIN
(SELECT
SUM(`GP`) AS `gptw`,
`Country`
FROM
Finance
WHERE DATEDIFF(NOW(), `date`) < 4
GROUP BY `Country`) AS `thisweek`
答案 0 :(得分:5)
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/