MySQL开窗函数over与group by进行olap数据分析

作用:

开窗函数类似于聚合函数(group by),主要实现数据的分组统计,在PostgreSQL中被称为窗口函数、在Oracle中被称为分析函数、在DB2中被称为OLAP函数。over在某些情况下可以完全替代group by,但大多情况下,over比group by更灵活、更强大。

优点:

1)同时具有分组和排序的功能

2)不减少原表的行数,经常用来在每组内排名

3)分组排序灵活

对比group by:

1)group by 只能得到分组后的统计数据,over partition by 不仅可以得到分组后的统计数据,还可以同时显示明细数据。

2)group by 是在where子句之后;over partition by 是from子句之前。

3)over比group by更灵活、更强大。

用法:

OVER ( [ PARTITION BY column ] [ ORDER BY culumn ] )

1)PARTITION BY 子句进行分组;

2)ORDER BY 子句进行排序。

3)窗口函数OVER()指定一组行,开窗函数计算从窗口函数输出的结果集中各行的值。

开窗函数不需要使用GROUP BY就可以对数据进行分组,还可以同时返回基础行的列和聚合列。

聚合函数一般指SUM(),MAX(),MIN,COUNT(),AVG()等常见函数。

排序函数一般指RANK(),ROW_NUMBER(),DENSE_RANK(),NTILE(),LEAD(),LAG(),STRING_AGG()等

CREATE TABLE `Employee` (

  `ID` int(11) NOT NULL,

  `NAME` varchar(20) DEFAULT NULL,

  `GroupName` varchar(20) DEFAULT NULL,

  `Salary` int(11) DEFAULT NULL,

  PRIMARY KEY (`ID`) /*T![clustered_index] CLUSTERED */

) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_bin
INSERT INTO `test`.`Employee`(`ID`, `NAME`, `GroupName`, `Salary`) VALUES (1, '小明', '开发部', 8000);

INSERT INTO `test`.`Employee`(`ID`, `NAME`, `GroupName`, `Salary`) VALUES (4, '小张', '开发部', 7600);

INSERT INTO `test`.`Employee`(`ID`, `NAME`, `GroupName`, `Salary`) VALUES (5, '小白', '开发部', 7000);

INSERT INTO `test`.`Employee`(`ID`, `NAME`, `GroupName`, `Salary`) VALUES (8, '小王', '财务部', 5000);

INSERT INTO `test`.`Employee`(`ID`, `NAME`, `GroupName`, `Salary`) VALUES (9, NULL, '财务部', NULL);

INSERT INTO `test`.`Employee`(`ID`, `NAME`, `GroupName`, `Salary`) VALUES (15, '小刘', '财务部', 6000);

INSERT INTO `test`.`Employee`(`ID`, `NAME`, `GroupName`, `Salary`) VALUES (16, '小高', '行政部', 4500);

INSERT INTO `test`.`Employee`(`ID`, `NAME`, `GroupName`, `Salary`) VALUES (18, '小王', '行政部', 4000);

INSERT INTO `test`.`Employee`(`ID`, `NAME`, `GroupName`, `Salary`) VALUES (23, '小李', '行政部', 4500);

INSERT INTO `test`.`Employee`(`ID`, `NAME`, `GroupName`, `Salary`) VALUES (29, '小吴', '行政部', 4700);

INSERT INTO `test`.`Employee`(`ID`, `NAME`, `GroupName`, `Salary`) VALUES (30, '小30', '行政部', 3333);

rank函数:这个例子中是4700,4500,4500,4000,3333,也就是如果有并列名次的行,会占用下一名次的位置。比如正常排名是1,2,3,4,5,但是现在2,3名是并列的名次,结果是:1,2,2,4,5。

dense_rank函数:这个例子中是4700,4500,4500,4000,3333,也就是如果有并列名次的行,不占用下一名次的位置。比如正常排名是1,2,3,4,5,但是现在2,3名是并列的名次,结果是:1,2,2,3,4。

row_number函数:这个例子中是4700,4500,4500,4000,3333,也就是不考虑并列名次的情况。比如前3名是并列的名次,排名是正常的1,2,3,4,5。

SELECT

        ID,

        NAME,

        GroupName,

        Salary,

        ranking,

        denseRank,

        rowNumber

FROM

        (

        SELECT

                ID,

                NAME,

                GroupName,

                Salary,

                rank ( ) over ( PARTITION BY GroupName ORDER BY Salary DESC ) AS ranking,

                dense_rank ( ) over ( PARTITION BY GroupName ORDER BY Salary DESC ) AS denseRank,

                row_number ( ) over ( PARTITION BY GroupName ORDER BY Salary DESC ) AS rowNumber

        FROM

                Employee

        ) newTb

WHERE

        ranking <= 5

        AND GroupName = '行政部'

 

DENSE_RANK()排名是连续的1-1-2-2-3排列--中国式排名,RANK()是跳跃的1-1-3 排列--美国式排名,ROW_NUMBER()是连续排序不跳跃,NTILE(N)把结果平分为N个分区, 如果不能均分,则优先多分前面的组

SELECT

        *,

        NTILE ( 5 ) OVER ( ORDER BY Salary DESC ) AS 分区后排序

FROM

        Employee;

 

https://blog.csdn.net/weixin_39740272/article/details/111090489

https://blog.csdn.net/navy0168/article/details/83737478

https://zhuanlan.zhihu.com/p/67656512

https://blog.csdn.net/weixin_39737492/article/details/110869246

https://stackoverflow.com/questions/39579224/using-group-by-and-over

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值