【问题标题】:MySQL SUMIFS with Dates带日期的 MySQL SUMIFS
【发布时间】:2020-04-07 08:29:38
【问题描述】:

在 MySQL 上遇到 SUMIFS 场景有困难

这是我的数据:

CREATE TABLE opportunities
(close_date DATE NOT NULL,
sale_amount DECIMAL NOT NULL);

INSERT INTO opportunities VALUES ('20190101',100);
INSERT INTO opportunities VALUES ('20190115',115);
INSERT INTO opportunities VALUES ('20190210',150);
INSERT INTO opportunities VALUES ('20190212',180);
INSERT INTO opportunities VALUES ('20190306',200);
INSERT INTO opportunities VALUES ('20190315',220);
INSERT INTO opportunities VALUES ('20190422',250);
INSERT INTO opportunities VALUES ('20190428',260);
INSERT INTO opportunities VALUES ('20190509',300);
INSERT INTO opportunities VALUES ('20190521',310);
INSERT INTO opportunities VALUES ('20190601',325);
INSERT INTO opportunities VALUES ('20190630',375);
INSERT INTO opportunities VALUES ('20190703',400);
INSERT INTO opportunities VALUES ('20190716',500);
INSERT INTO opportunities VALUES ('20190813',550);
INSERT INTO opportunities VALUES ('20190814',575);
INSERT INTO opportunities VALUES ('20190909',625);
INSERT INTO opportunities VALUES ('20190929',650);
INSERT INTO opportunities VALUES ('20191004',700);
INSERT INTO opportunities VALUES ('20191022',750);
INSERT INTO opportunities VALUES ('20191112',800);
INSERT INTO opportunities VALUES ('20191119',900);
INSERT INTO opportunities VALUES ('20191202',950);
INSERT INTO opportunities VALUES ('20191216',975);

我需要完成的是每个月有 1 行(例如 2019-01、2019-02、2019-03 等),对于该行,我需要为前 6 个月。因此,2019-12 年的 sale_amount 将等于所有 sale_amounts 的总和,close_date 为 2019 年 7 月 1 日至 2019 年 12 月 31 日。根据我提供的数据,我需要我的最终结果如下所示:

Month       Sale_Amount (Prev 6 Months)
2019-01     215
2019-02     545
2019-03     965
2019-04     1475
2019-05     2085
2019-06     2785
2019-07     3470
2019-08     4265
2019-09     5120
2019-10     6060
2019-11     7150
2019-12     8375

到目前为止,这是我尝试过的:

SELECT
    DATE_FORMAT(op.close_date, '%Y-%m'),
    SUM(CASE
    WHEN op.close_date >= DATE_FORMAT(DATE_SUB(op.close_date, INTERVAL 5 MONTH) ,'%Y-%m-01')
        AND op.close_date <= LAST_DAY(op.close_date) THEN op.sale_amount
    END)
FROM opportunities op
GROUP BY DATE_FORMAT(op.close_date, '%Y-%m')
ORDER BY DATE_FORMAT(op.close_date, '%Y-%m')

这不起作用,它只返回当月的总和

我得到的实际结果:

Month       Sale_Amount (Prev 6 Months)
2019-01     215
2019-02     330
2019-03     420
2019-04     510
2019-05     610
2019-06     700
2019-07     900
2019-08     1125
2019-09     1275
2019-10     1450
2019-11     1700
2019-12     1925

我正在尝试将其从 Excel 电子表格转换,下面的公式完全符合我的预期,但不确定如何转换为 MySQL

SUMIFS($B$2:$B$500, --sum range
$A$2:$A$500,">="&DATE(YEAR(EOMONTH(A2,-6)+1),MONTH(EOMONTH(A2,-6)+1),1), --close_date >= than first day 6 months ago
$A$2:$A$500,"<="&DATE(YEAR(A2),MONTH(A2),DAY(EOMONTH(A2,0)))) --close date <= last date of current month

希望我的问题足够清楚,在此先感谢

【问题讨论】:

  • 您运行的是哪个版本的 MySQL?
  • @GMB 不得不问,显然是 vers。 5.7.26 ...刚刚意识到我搞砸了,因为我收到的答案包括一个窗口功能,除非我在 8.0+ 中,否则显然不支持它

标签: sql group-by rmysql


【解决方案1】:

使用窗口函数:

SELECT DATE_FORMAT(op.close_date, '%Y-%m'),
       SUM(op.sale_amount) as this_month,
       SUM(op.sale_amount) OVER (ORDER BY MIN(op.close_date) ROWS BETWEEN 5 PRECEDING AND CURRENT ROW) as running_6_months
FROM opportunities op
GROUP BY DATE_FORMAT(op.close_date, '%Y-%m')
ORDER BY DATE_FORMAT(op.close_date, '%Y-%m');

【讨论】:

  • 谢谢,没有想到使用窗口函数,尽管由于某种原因我无法使用 SQL Fiddle 运行它。除了 ORDER 的拼写错误,我不知道是什么问题
  • SUM(SUM(op.sale_amount)) 必须是 SUM(op.sale_amount)
  • @nbk 在 SQL Fiddle 上仍然不适合我,嗯。它说“您的 SQL 语法有错误;请查看与您的 MySQL 服务器版本相对应的手册,以了解在 '(ORDER BY MIN(op.close_date) ROWS BETWEEN 5 PRECEDING AND CURRENT ROW) as runnin' 附近使用的正确语法在第 3 行“
  • dbfiddle 有更多的限制,因为它运行在我的 mysql 服务器上,所以请在家庭服务器上尝试一下
  • 是的,我实际上没有使用 8.0,而是 5.7.26 版本。太烂了,毕竟不能用这个答案
【解决方案2】:

这里是 MySQL

select d.close_month, sum(o.sale_amount) sale_amount
from 
    (select distinct date_format(close_date, '%Y-%m-01') close_month from opportunities) d
    inner join opportunities o
        on o.close_date < close_month + interval 1 month
        and o.close_date >= close_month - interval 5 month
group by d.close_month
order by d.close_month

这是通过生成一个不同月份的列表,将其与最近 6 个月的表连接起来,然后进行聚合来实现的。

Demo on DB Fiddle

close_month |销售金额 :------------ | ----------: 2019-01-01 | 215 2019-02-01 | 545 2019-03-01 | 965 2019-04-01 | 1475 2019-05-01 | 2085 2019-06-01 | 2785 2019-07-01 | 3470 2019-08-01 | 4265 2019-09-01 | 5120 2019-10-01 | 6060 2019-11-01 | 7150 2019-12-01 | 8375

【讨论】:

  • 病了!!这在 MySQL 5.7 上非常适合我。谢谢!!
猜你喜欢
  • 1970-01-01
  • 2022-11-17
  • 1970-01-01
  • 2021-10-07
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多