【问题标题】:How to create an SQL window function column per category in MySQL?如何在 MySQL 中为每个类别创建一个 SQL 窗口函数列?
【发布时间】:2021-08-20 14:40:23
【问题描述】:

我正在使用 MySQL 在另一列中为每个类别创建一个窗口函数。我正在考虑可能将数据透视表与窗口函数结合起来,但是,不知道如何用 MySQL 做数据透视表。

以下是我的想法,为每个类别创建一个列并计算给定时间范围内的平均值:

我有:

firstname lastname category amount timestamp
Tom Sta hair 1 2020-06-21
Chris Danny school 2 2020-06-22
Gee Elle books 1 2020-06-21
Tom Sta books 10 2020-06-23
Chris Danny hair 2 2020-06-25
Gee Elle school 15 2020-06-28

我想要:

firstname lastname hair_last_3_days school_last_3_days boks_last_3_days
Tom Sta 1 1 21
Chris Danny 2 2 202
Gee Elle 2 1 1
Tom Sta 4 10 6
Chris Danny 3 2 0
Gee Elle 2 15 28

目前我能够创建平均值

select first, last, date(trans_date_trans_time), amt, category,
avg(amt) over(partition by first, last, category order by date(trans_date_trans_time) ROWS BETWEEN 2 PRECEDING AND CURRENT ROW) avg_last_3 from table;

但是我意识到,这只有在日子一个接一个的情况下才有效,如果一个人在同一天有两行,这将不起作用。我正在寻求帮助。谢谢

【问题讨论】:

    标签: mysql sql window-functions rolling-average


    【解决方案1】:

    如果您有全天的数据,那么您可以在avg() 中使用条件逻辑:

    select first, last, date(trans_date_trans_time), amt, category,
           avg(case when category = 'hair' then amt enfd) over
               (partition by first, last, category
                order by date(trans_date_trans_time)
                ROWS BETWEEN 2 PRECEDING AND CURRENT ROW
               ) as avg_hair_last_3
    from table;
    

    但更好的解决方案是使用时间窗口框架:

    select first, last, date(trans_date_trans_time), amt, category,
           avg(case when category = 'hair' then amt enfd) over
               (partition by first, last, category
                order by date(trans_date_trans_time)
                rows between interval 2 day preceding and current row
               ) as avg_hair_last_3
    from table;
    

    【讨论】:

      【解决方案2】:

      如果是我,我会执行类似以下的操作,并处理应用程序代码中的任何剩余问题...

      SELECT x.firstname
           , x.lastname
           , x.category
           , SUM(amount) total
        FROM my_table x
        JOIN 
           ( SELECT firstname  
                  , lastname
                  , category
                  , MAX(timestamp) timestamp
               FROM my_table
              GROUP 
                 BY firstname
                  , lastname
                  , category
           ) y
          ON y.firstname = x.firstname 
         AND y.lastname = x.lastname
         AND y.category = x.category
         AND x.timestamp BETWEEN y.timestamp - INTERVAL 2 DAY AND y.timestamp
       GROUP
          BY x.firstname
           , x.lastname
           , x.category 
      

      请注意,这不是任何事情的“平均值”,因为我不太了解您的结果集如何与您的数据集匹配。

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2021-10-09
        • 2021-07-26
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多