如何在 MySQL 中为每个类别创建一个 SQL 窗口函数列?
Posted
技术标签:
【中文标题】如何在 MySQL 中为每个类别创建一个 SQL 窗口函数列?【英文标题】:How to create an SQL window function column per category in MySQL? 【发布时间】: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;
但是我意识到,这只有在日子一个接一个的情况下才有效,如果一个人在同一天有两行,这将不起作用。我正在寻求帮助。谢谢
【问题讨论】:
【参考方案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
请注意,这不是任何事情的“平均值”,因为我不太了解您的结果集如何与您的数据集匹配。
【讨论】:
以上是关于如何在 MySQL 中为每个类别创建一个 SQL 窗口函数列?的主要内容,如果未能解决你的问题,请参考以下文章