在 SQL 中使用 Over 和 Partition

Posted

技术标签:

【中文标题】在 SQL 中使用 Over 和 Partition【英文标题】:Using Over & Partition in SQL 【发布时间】:2018-11-27 09:53:47 【问题描述】:

我有一个 SQL 表,其中包含不同类别(例如水果、蔬菜、乳制品)产品的月度价格。 我想在同一个查询中计算特定类别和同一个月内所有产品的每月平均运行平均值。

所以结合:

Select date, avg(price) group by date where category = 'Fruit'

Select date, avg(price) group by date

是否可以使用 OVER & Partition(或任何其他方式)

编辑

我正在使用 MS SQL 我的数据是每月的,所以我不需要提取月末日期 - 我可以按日期分组,然后我会得到月末数据 例如,如果我的表如下所示:

|日期|项目 |类别 |价格 | |一月 |香蕉 |水果 | 10| |一月 |马铃薯 |蔬菜 | 20 |

那么输出将是

日期 |水果平均 |总体平均 | 一月 | 10 | 15

为破坏表格提前道歉,但这是另一个线程。

谢谢

【问题讨论】:

添加一些示例表数据和预期结果 - 全部作为格式化文本,而不是图像。顺便说一句,GROUP BY 在 WHERE 之后。 您使用的是哪个 dbms? 【参考方案1】:

为什么需要结束?

Select date, category , avg(price) group by date, category 

【讨论】:

【参考方案2】:

尝试使用

Select extract(year from date)||extract(month from date) as month, 
       category, avg(price) as avg_price            
  from sales
 group by month, category

附:某些数据库系统可能不允许使用别名 month,在这种情况下,将分组列表中的月份替换为 extract(year from date)||extract(month from date)。连接运算符也可能不同,只要遇到这种情况,请将管道(||)替换为加号(+)。

【讨论】:

【参考方案3】:

如果您希望每个月有一行并且数据有多行,那么您需要聚合:

select date_trunc('month', date) as month, 
       avg(price) as avg_per_month,
       avg(avg(price)) over (order by date_trunc('month', date))
from t
where category = 'Fruit'
group by date_trunc('month', date)
 order by date_trunc('month', date);

如果你每个月只有一行,那么你可以这样做:

select date, price,
       avg(price) over (order by date)
from t
where category = 'Fruit'
order by date;

【讨论】:

以上是关于在 SQL 中使用 Over 和 Partition的主要内容,如果未能解决你的问题,请参考以下文章

Oracle over函数

SQL |如何对 3 个项目的分区组求和?

oracle的row_number()over rank()over和dense_rank()over这三种分析函数(转)

在 SQL 中使用 Over 和 Partition

cume_dist(),允许并列名次复制名次自动空缺,取并列后较大名次,结果如22355778……

关于SQL的over partition by 开窗语句在分页和统计中的使用总