mysql实现开窗函数
mysql实现开窗函数
http://blog.itpub.net/29989552/viewspace-2123077/
学习过oracle的应该知道,oracle中的分析函数功能十分强大,包括mssql、postgresql等数据库都支持开窗函数。然而mysql至今都没有提供这样的功能,今天就来探讨下用mysql实现一些开窗功能需求。
实验数据:表sale
| month | user_id | amount |
+--------+---------+--------+
| 201601 | 1 | 500 |
| 201601 | 2 | 300 |
| 201601 | 3 | 100 |
| 201602 | 1 | 1000 |
| 201602 | 2 | 800 |
| 201603 | 2 | 1000 |
| 201603 | 3 | 500 |
| 201604 | 1 | 1000 |
需求一:求每个月的销售额及累计销售额(二月份额累计销售额是一月销售额加二月销售额)
开窗函数实现:
select month,sum(amount),sum(sum(amount)) over (ORDER BY month) from sale GROUP BY month ORDER BY month
month | sum | sum
--------+------+------
201601 | 900 | 900
201602 | 1800 | 2700
201603 | 1500 | 4200
201604 | 1000 | 5200
轻松完成需求
mysql实现:
select
a.month,a.amount,sum(b.amount)
from (select month,sum(amount) amount from sale GROUP BY month) a CROSS JOIN (select month,sum(amount) amount from sale GROUP BY month) b
where a.month>=b.month GROUP BY a.month,a.amount
+--------+--------+---------------+
| month | amount | sum(b.amount) |
+--------+--------+---------------+
| 201601 | 900 | 900 |
| 201602 | 1800 | 2700 |
| 201603 | 1500 | 4200 |
| 201604 | 1000 | 5200 |
可以看出相比较于开窗函数,mysql实现起来很麻烦,先用子查询将每个月的销售汇总,再将两个子查询做笛卡尔积,性能肯定比开窗差很多,如果子查询结果集很多,做笛卡尔积是个灾难!
需求二:每个月销售冠军及销售额
开窗函数实现:
select month,user_id,amount
from
(select
month,user_id,amount,
row_number() over (PARTITION by month ORDER BY amount desc) rn
from sale) a where a.rn=1
month | user_id | amount
--------+---------+--------
201601 | 1 | 500
201603 | 2 | 1000
201602 | 1 | 1000
201604 | 1 | 1000
mysql实现:
方法一:
select a.*
from (select t1.*,
(select count(*) + 1
from sale
where month = t1.month
and amount > t1.amount) as group_id
from sale t1) a
where a.group_id = 1;
+--------+---------+--------+----------+
| month | user_id | amount | group_id |
+--------+---------+--------+----------+
| 201601 | 1 | 500 | 1 |
| 201603 | 2 | 1000 | 1 |
| 201602 | 1 | 1000 | 1 |
| 201604 | 1 | 1000 | 1 |
+--------+---------+--------+----------+
这个样的方式同样是用笛卡尔积得出和开窗rank一样的结果列出来
方法二:
select month,user_id,max(amount) from sale GROUP BY month
| month | user_id | max(amount) |
+--------+---------+-------------+
| 201601 | 1 | 500 |
| 201602 | 1 | 1000 |
| 201603 | 2 | 1000 |
| 201604 | 1 | 1000 |
mysql实现起来简单,但是注意,这个语句是不严谨的,因为user_id没有跟在group by后面,这是其他数据库所不允许。在mysql5.6中默认的sql_mode只有NO_ENGINE_SUBSTITUTIO,这样的语法可以使用,如果sql_mode有ONLY_FULL_GROUP_BY的限制,则无法使用这样的语法。mysql5.7的sql_mode就默认含有ONLY_FULL_GROUP_BY。
f
mysql实现开窗函数的更多相关文章
- mysql实现开窗函数、Mysql实现分析函数
关键字:mysql实现开窗函数.Mysql实现分析函数.利用变量实现窗口函数 注意,变量是从左到右顺序执行的 --测试数据 CREATE TABLE `tem` ( `id` ) NOT NULL A ...
- mysql为何不支持开窗函数?
引用 在开窗函数出现之前存在着非常多用 SQL 语句非常难解决的问题,非常多都要通过复杂的相关子查询或者存储过程来完毕.为了解决这些问题,在2003年ISO SQL标准增加了开窗函数,开窗函数的使用使 ...
- mysql 实现类似开窗函数的功能
mysql8 已经支持开窗函数 https://dev.mysql.com/doc/refman/8.0/en/window-functions.html ———————————————— sql s ...
- Mysql 开窗函数实战
Mysql 开窗函数实战 Mysql 开窗函数在Mysql8.0+ 中可以得以使用,实在且好用. row number() over rank() over dense rank() ntile() ...
- Oracle开窗函数 over()(转)
copy文链接:http://blog.csdn.net/yjjm1990/article/details/7524167#,http://www.2cto.com/database/201402/2 ...
- (MariaDB)开窗函数用法
本文目录: 1.1 窗口和开窗函数简介 1.2 OVER()语法和执行位置 1.3 row_number()对分区排名 1.4 rank()和dense_rank() 1.5 percent_rank ...
- SQL之开窗函数详解--可代替聚合函数使用
在没学习开窗函数之前,我们都知道,用了分组之后,查询字段就只能是分组字段和聚合的字段,这带来了极大的不方便,有时我们查询时需要分组,又需要查询不分组的字段,每次都要又到子查询,这样显得sql语句复杂难 ...
- (011)每日SQL学习:SQL开窗函数
开窗函数:在开窗函数出现之前存在着很多用 SQL 语句很难解决的问题,很多都要通过复杂的相关子查询或者存储过程来完成.为了解决这些问题,在 2003 年 ISO SQL 标准加入了开窗函数,开窗函数的 ...
- Mysql - 存储过程/自定义函数
在数据库操作中, 尤其是碰到一些复杂一些的系统, 不可避免的, 会用到函数/自定义函数, 或者存储过程. 实际项目中, 自定义函数和存储过程是越少越好, 因为这个东西多了, 也是一个非常难以维护的地方 ...
随机推荐
- __name__的意义与作用
首先定义了一个test.py的文件,然后再定义一个函数,并在函数定义后直接运行: test.py def HaveFun(): if __name__ == '__main__': print(' ...
- OpenCV-Python教程9-平滑图像
先解释一个单词 blur:使...模糊不清 滤波与模糊 滤波和模糊都属于卷积,不同的滤波方法之间只是卷积核不同(对线性滤波而言) 低通滤波器是模糊,高通滤波器是锐化 低通滤波器允许低频信号通过,在图像 ...
- windows环境jprofiler配置监控tomcat
1.点击jprofiler/bin/jprofiler.exe文件安装 2.安装后将C:\Users\Administrator\.jprofiler8\config.xml文件复制到指定文件下,如: ...
- elasticsearch单机部署多个节点
cp -r elasticsearch-2.4.4 elasticsearch-2.4.4-2 mv elasticsearch-2.4.4 elasticsearch-2.4.4-1 总共cp了三个 ...
- Java_打印从一个数到另一个数之间的整数,并每5个为一行
import java.util.Scanner; public class Dayin_100 { public static void main(String[] args) { System.o ...
- Git基本操作指令
Git是世界上目前最先进的分布式版本控制系统. 工作原理图: Workspace工作区,Index暂存区,Repository本地仓库区,Remote远程仓库. SVN与Git的最主要的区别? SVN ...
- jsonwebtoken收藏博客地址
这个东西也不是很懂,但是查了一下资料,大概知道是什么了,具体要怎么嵌套到具体自己需要实现的功能里面,这个跨度还是有点大, 先把博客地址给收藏了. 这里是Java版示例 简书参考 js示例 github ...
- http动词解释及规范
GET:GET用于信息获取,而且应该是安全的和幂等的. 安全的意味着该操作用于获取信息而非修改信息,不管进行多少次操作,资源的状态都不会改变. 幂等的意味着对同一URL的多个请求应该返回同样的结果. ...
- angularJs实现数据双向绑定的原理
angular1.x在指定的事件触发时(比如dom事件,xhr响应事件,浏览器定位变更事件,定时器事件),通过脏值检测的方式比对数据是否有变更,来决定是否更新视图. angular2使用了zone.j ...
- 第八篇 Flask配置
Flask 是一个非常灵活且小而精的web框架 , 那么灵活性从什么地方体现呢? 列如 Flask配置,这个东西怎么用呢? 它能给我们带来怎么样的方便呢? app配置 首先展示一下: from fl ...