【问题标题】:Get sum of values for multiple categories for a given list of dates获取给定日期列表的多个类别的值总和
【发布时间】:2022-01-22 16:55:34
【问题描述】:

我需要编写一个查询来获取给定日期列表中每个类别的值的总和。如果某个类别的值不存在,我们应该从上一个日期获取值。基本上类似于“每个日期每个类别的最大值”。最终目标是趋势图。如果某个类别的先前值不存在,则将该值设置为 0 即可。

见下表和结果:

类别

id name
1 savings
2 cash
3 stocks

物品

id categoryId value createdAt
1 1 100 2022-01-01
2 2 20 2022-01-01
3 3 500 2022-01-01
4 2 0 2022-01-02
5 3 1000 2022-01-03

结果

createdAt total
2022-01-01 620
2022-02-02 600
2022-02-03 1100

要获得一个日期的结果,我可以这样做:

SELECT SUM(value) as total
FROM Category
LEFT JOIN (
    SELECT id, categoryId, value
    FROM Item
    WHERE id IN (
        SELECT MAX(id) FROM Item WHERE createdAt <= '2022-01-10' GROUP BY categoryId)
) items ON Category.id = items.categoryId;

我完全不知道如何在多个日期执行此操作,例如。如果我的输入是 2022 年 1 月的每一天。我在 MySQL 8.0.23 上运行。此外,如果这对单个查询不可行,我会提出想法。你有什么建议吗?

【问题讨论】:

    标签: mysql sql aggregate-functions mysql-8.0


    【解决方案1】:

    试试这个:

    with u as
    (select id as categoryId from Category),
    v as
    (select distinct createdAt from Item),
    w as
    (select * from u cross join v),
    x as
    (select createdAt, 
    categoryId, 
    (select value 
    from Item 
    where categoryId = w.categoryId and createdAt <= w.createdAt 
    order by createdAt desc 
    limit 1) as value
    from w)
    select createdAt, sum(value) as total
    from x
    group by createdAt
    

    基本上是获取创建日期与 categoryIds 的所有组合,然后使用子查询获取每个 categoryId 的最接近或相等日期的值。

    Fiddle.

    【讨论】:

    • 谢谢扎卡利亚!这正是我希望实现的目标:)太好了。
    【解决方案2】:

    一个选项使用窗口函数如SUM() OVER ()LAG()

    WITH i AS
    (
     SELECT SUM(`value`) OVER (PARTITION BY `createdAt`,`categoryId` ORDER BY `createdAt`) AS total_sofar,
            LAG(`value`,1,0) OVER (PARTITION BY `categoryId` ORDER BY `createdAt`) AS lg,
            `createdAt`
       FROM Item 
    )
    SELECT DISTINCT `createdAt`,
           SUM(total_sofar) OVER (ORDER BY `createdAt`)-SUM(lg) OVER (ORDER BY `createdAt`) AS total
      FROM i
     ORDER BY `createdAt` 
    

    因为您拥有 8.0 版的 MySQL DBMS。诀窍是分组(分区categoryIdLAG 在第一个查询)

    Demo

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2021-11-04
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2020-10-18
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多