【问题标题】:how to show week over week in sql如何在sql中显示一周一周
【发布时间】:2014-07-21 21:22:24
【问题描述】:

我需要在一周内显示两列 GP 总和的计算列,并在另一列中显示前一列

我认为我的方法是正确的,但我错过了一些东西

我试图让我的结果是这样的::

|每周|日本|澳大利亚|英国|

|上一页|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` 

【问题讨论】:

  • 你的问题不清楚,你需要定义到底是什么问题
  • 请告诉我们输出/错误是什么

标签: mysql datetime time-series aggregate


【解决方案1】:

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/

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2017-12-18
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多