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 - 存储过程/自定义函数
在数据库操作中, 尤其是碰到一些复杂一些的系统, 不可避免的, 会用到函数/自定义函数, 或者存储过程. 实际项目中, 自定义函数和存储过程是越少越好, 因为这个东西多了, 也是一个非常难以维护的地方 ...
随机推荐
- CentOS 7 中 Systemd详解
一.systemd的由来 Linux一直以来采用init进程但是init有两个缺点: 1.启动时间长.Init进程是串行启动,只有前一个进程启动完,才会启动下一个进程.(这也是CentOS5的主要特征 ...
- docker安装 <一>
一.docker简介 Docker 是一个开源的应用容器引擎,让开发者可以打包他们的应用以及依赖包到一个可移植的容器中,然后发布到任何流行的Linux机器上,也可以实现虚拟化,容器是完全使用沙箱机制, ...
- [原创]FPGA JTAG工具设计(二)
经过前期打样 基于FT2232H的JTAG &UART板级已经初步形成 在Viado环境和ISE(13.2+)环境可以使用 速度支持10MHz/15MHz/30MHz 在ISE iMpact下 ...
- 设计模式学习之访问者模式(Visitor,行为型模式)(21)
参考:https://www.cnblogs.com/edisonchou/p/7247990.html 在患者就医时,医生会根据病情开具处方单,很多医院都会存在以下这个流程:划价人员拿到处方单之后根 ...
- SpringMVC-2-(Controller)
一)参数类型 @RequestMapping("hello4") @ResponseBody public ModelAndView Hello4( // Servlet的三个参数 ...
- C#使用CefSharp碰到的坑(一)
使用CEFSharp做模拟提交的话,在高版本下会出现一个神奇的错误: 如果站点使用的是阿里提供的验证控件的话,就是那种拖动条的,如果是使用CEFSharp的新版本的(目前我是测试过70的) ,会出现拖 ...
- 【JavaScrpt】用js创建html上的元素
// 在body下创建一个div var createDiv=document.createElement("div"); createDiv.id='id_i'; createD ...
- PropertyEditor、Formatter、Converter的应用
@ResponseBody @RequestMapping("date.do") public String data(Date date) { return date.toStr ...
- __x__(5)0905第二天__网页三大组成部分
根据 W3C 标准,将网页主要分成 3 个部分:结构,表现,行为. 结构: HTML 用于描述页面结构. 表现: CSS 用于控制页面中元素的样式. 行为: JavaScript 用于响应用户操作.
- __x__(43)0910第六天__ clearfix 解决:垂直外边距重叠,高度塌陷
<div class="box1"> <tabl></table> <div class="box2">< ...