【问题标题】:SQL Select sum of previous month group by dateSQL按日期选择上个月组的总和
【发布时间】:2021-05-31 05:52:33
【问题描述】:

我在 MySQL 数据中有下表

CREATE TABLE `new_table` (
  `date1` varchar(20) DEFAULT NULL,
  `organisation` varchar(45) DEFAULT NULL,
  `proportion` varchar(45) DEFAULT NULL,
  `id` int NOT NULL AUTO_INCREMENT,
  PRIMARY KEY (`id`)
) ENGINE=InnoDB AUTO_INCREMENT=5 DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_0900_ai_ci;

INSERT INTO `new_table` (`date1`, `organisation`, `proportion`) VALUES ('7/31/2020', 'Clinical Services', '50');
INSERT INTO `new_table` (`date1`, `organisation`, `proportion`) VALUES ('7/31/2020', 'Data and analytics', '60');
INSERT INTO `new_table` (`date1`, `organisation`, `proportion`) VALUES ('8/31/2020', 'Clinical Services', '12');
INSERT INTO `new_table` (`date1`, `organisation`, `proportion`) VALUES ('8/31/2020', 'Data and analytics', '40');
INSERT INTO `new_table` (`date1`, `organisation`, `proportion`) VALUES ('9/30/2020', 'Clinical Services', '25');
INSERT INTO `new_table` (`date1`, `organisation`, `proportion`) VALUES ('9/30/2020', 'Data and analytics', '20');

我想通过date1分别得到date1proportion组的总和,分别为openingclosing,条件如下

  1. 如果存在上个月的数据,则上个月的SUM(proportion) 为当月的opening,当月的SUM(proportion)closing
  2. 当上个月的数据不存在时,SUM(proportion) 是当月的开盘。

结果表应该是

Date opening closing
7/31/2020 110 110
8/31/2020 110 52
9/20/2020 52 45

我正在使用以下查询

SELECT
    date1 as 'Date',
    CASE
        WHEN (
            SELECT
                SUM(proportion)
            FROM
                new_table
            WHERE
                MONTH(str_to_date(date1, '%m/%d/%Y')) = MONTH(str_to_date(date1, '%m/%d/%Y')) - 1
            GROUP BY date1
            LIMIT 1
        ) > 0
        THEN (
            SELECT
                SUM(proportion)
            FROM new_table
            WHERE
                MONTH(str_to_date(date1, '%m/%d/%Y')) = MONTH(str_to_date(date1, '%m/%d/%Y')) - 1
            GROUP BY date1
            LIMIT 1
        )
        ELSE (
            SELECT
                sum(proportion)
            FROM new_table
            WHERE
                MONTH(str_to_date(date1, '%m/%d/%Y')) = MONTH(str_to_date(date1, '%m/%d/%Y'))
            GROUP BY date1
            LIMIT 1
        )
    END as 'Opening',
    SUM(proportion) as 'Closing'
FROM new_table
GROUP BY date1

但它给出了以下输出,其中Opening 对于所有行都是相同的。

示例:https://paiza.io/projects/Jgbxf3Xxag8fKIb3OuasjA?language=mysql

【问题讨论】:

  • 您使用的是哪个版本的 MySQL?请您以文本格式分享示例数据。
  • 我已经用示例数据和编辑器更新了问题。
  • @Strawberry 如果您的意思是 date1 列,那么实际上使用的数据源具有 VARCHAR 列。我无权修改它。
  • 为什么Closing 的最后一个日期是 45 而 24+35=59?
  • @Akina 这个问题是由某人使用导致不匹配的示例数据编辑的。我已经更新了问题中的相同数据。

标签: mysql sql


【解决方案1】:
SELECT str_to_date(date1, '%m/%d/%Y') date1, 
       COALESCE(LAG(SUM(proportion)) OVER (ORDER BY str_to_date(date1, '%m/%d/%Y')), 
                SUM(proportion)) opening,
       SUM(proportion) closing
FROM new_table
GROUP BY date1

fiddle

如果月份中的日期可能不同,请使用LAST_DAY(str_to_date(date1, '%m/%d/%Y'))

PS。使用了两个源数据值:取自问题文本和链接中的小提琴。

【讨论】:

    【解决方案2】:

    我已经重现了这种情况。您可以使用 Lag()Over() 来实现您正在寻找的内容:

    select date1,coalesce( lag(sumprop,1)over( order by date1) ,sumprop) Opening,sumprop Closing  from (
    select date1,sum(proportion) sumprop from new_table
    group by date1)t
    

    db-fiddle 链接:

    https://www.db-fiddle.com/#&togetherjs=PieI81lvNT

    对于旧版本的 MySQL:

    select date1,coalesce((select sum(proportion) from new_table NT WHERE NT.DATE1<N.DATE1),sum(proportion)) Opening,
                  sum(proportion)  Closing from new_table N
    group by date1 
    

    【讨论】:

    • 因为你没有考虑到年份的界限。
    • 对于旧版本的 MySQL: 在 paiza.io 上提供小提琴使用 8.0.22。
    • @Strawberry 边界有什么问题?也许您的意思是日期列数据类型为 varchar 格式不正确?
    • @Strawberry 。 . .问题中没有任何内容明确提到年份界限是一个问题。
    • @Strawberry 你能详细说明一下吗?我刚刚尝试解决问题中提到的问题。很高兴从我的错误中吸取教训。
    猜你喜欢
    • 1970-01-01
    • 2010-10-30
    • 2018-12-24
    • 1970-01-01
    • 2017-04-24
    • 1970-01-01
    • 2013-08-29
    • 2012-03-30
    • 1970-01-01
    相关资源
    最近更新 更多