简体   繁体   中英

SQL Select sum of previous month group by date

I have the following table in the MySQL Data

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');

I want to get the date1 and the sum of the proportion group by date1 as opening and closing respectively with the following condition

  1. When data exists for the previous month, then SUM(proportion) of the previous month as the opening for the current month and SUM(proportion) of the current month as the closing .
  2. When data does not exist for the previous month, SUM(proportion) is the opening for the current month.

The resultant table should be

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

I'm using the following query

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

But it is giving the following output where Opening is the same for all the rows.

在此处输入图像描述

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

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

If the date within the month may differ then use LAST_DAY(str_to_date(date1, '%m/%d/%Y')) .

PS. Two sourse data values are used: taken from the question text and from the fiddle by the link.

I have recreate the situation. You can use Lag()Over() to achieve what you are looking for:

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 link:

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

For older version of 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 

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM