关键字:mysql实现开窗函数、Mysql实现分析函数、利用变量实现窗口函数

适用范围:mysql5.7及以下版本,mysql8.0+ 可以直接使用窗口函数

注意,变量是从左到右顺序执行的

-- 测试数据
CREATE TABLE `tem` (
`id` int(11) NOT NULL AUTO_INCREMENT,
`str` char(1) DEFAULT NULL,
PRIMARY KEY (`id`)
) ; INSERT INTO `test`.`tem`(`id`, `str`) VALUES (1, 'A');
INSERT INTO `test`.`tem`(`id`, `str`) VALUES (2, 'B');
INSERT INTO `test`.`tem`(`id`, `str`) VALUES (3, 'A');
INSERT INTO `test`.`tem`(`id`, `str`) VALUES (4, 'C');
INSERT INTO `test`.`tem`(`id`, `str`) VALUES (5, 'A');
INSERT INTO `test`.`tem`(`id`, `str`) VALUES (6, 'C');
INSERT INTO `test`.`tem`(`id`, `str`) VALUES (7, 'B');

【1】row_number() over(order by )

变量会最后再计算,所以是先排序好之后,才会开始计算@num

SELECT
@num := @num+1 num,
id,
str
FROM
tem, (SELECT @str := '', @num := 0) t1
ORDER BY
str, id;


【2】实现分组排名效果(row_number() over(partition by order by ))

--变量方式
SELECT
@num := IF(@str = str, @num + 1, 1) num,
id,
@str := str str
FROM
tem, (SELECT @str := '', @num := 0) t1
ORDER BY
str, id;


--子查询方式【取分组中前N行(排名前几名)】
mysql 相关子查询参考
select * from testGroup as a
where a.ID in (select ID from testGroup b where a.UserID = b.UserID order by b.OrderID limit 2)
--或者
select * from testGroup a
where not exists (select 1 from testGroup b where a.UserID = b.UserID and a.OrderID > b.OrderID
having count(1) >= 2)
--或者
select * from testGroup a
where (select count(1) from testGroup b where a.UserID = b.UserID and a.ID >= b.ID) <= 2
--没有唯一标识的表,可以用checksum来标识每行(MSSQL?)
select * from testGroup as a
where checksum(*) in (select top 2 checksum(*) from testGroup b where a.UserID = b.UserID order by b.OrderID)
mysql使用子查询实现
create table test1_1(id int auto_increment primary key,`subject` char(20),score int);
insert into test1_1 values(null,'语文',99),(null,'语文',98),(null,'语文',97);
insert into test1_1 values(null,'数学',89),(null,'数学',88),(null,'数学',87);
insert into test1_1 values(null,'英语',79),(null,'英语',78),(null,'英语',77); -- 根据成绩,求出每个科目的前2名 select * from test1_1; select * from test1_1 t1
where (select count(1) from test1_1 t2 where t1.subject=t2.subject and t2.score>=t1.score ) <=2; -- 查询结果【左边】原表内容  【右边】需求结果,根据成绩,求出每个科目的前2名

 



【3】实现dense_rank() over(order by)

--变量会最后再计算,所以是先排序好之后,才会开始计算@num

select id,@num:=IF(@STR=STR,@num,@num+1) rn,@str:=str str
from tem t1,(select @str:='',@num:=0) t2
order by str
--

---case when 形式,但该方法在mysql5.5中,只支持非0数字排序生成,字符会有大问题(任意字符被case when 'a' then else end,都会走else)

--且,赋值语句等于0时也为假

--错误的方式
select id,str,
case when @str=str then @num
when @str:=str then @num:=@num+1 end as 'rn'
from tem t1,(select @str:='',@num:=1) t2
order by str
  

  

--正确的方式
select id,str,
case when @str=str then @num
when @str:=str then @num:=@num+1
else @num:=@num+1 end as 'rn'
from tem t1,(select @str:='',@num:=0) t2
order by str   
 

--关于数字的case when 验证

  

关于字符、字符串 的case when验证
  

  


【4】rank() over()

  

  

---------------------
测试数据代码大部分引用自:https://blog.csdn.net/mingqing6364/article/details/82621840

mysql实现开窗函数、Mysql实现分析函数的更多相关文章

  1. mysql实现开窗函数

    mysql实现开窗函数 http://blog.itpub.net/29989552/viewspace-2123077/ 学习过oracle的应该知道,oracle中的分析函数功能十分强大,包括ms ...

  2. oracle的分析函数over 及开窗函数

    转:http://www.2cto.com/database/201310/249722.html oracle的分析函数over 及开窗函数   一:分析函数over   Oracle从8.1.6开 ...

  3. oracle 分析函数和开窗函数

    最近遇到一个需求,将查询出的数据按照地区分组,随机取出每个区域的2条数据,这里用到了oracle的分析和开窗函数: 最终写出的sql如下: select * from (select region,r ...

  4. 超级牛皮的oracle的分析函数over(Partition by...) 及开窗函数 (转)

    http://zonghl8006.blog.163.com/blog/static/4528311520083995931317/ over(Partition by...) 一个超级牛皮的ORAC ...

  5. 超级牛皮的oracle的分析函数over(Partition by...) 及开窗函数

    over(Partition by...) 一个超级牛皮的ORACLE特有函数. 天天都用ORACLE,用了快2年了.最近才接触到这个功能强大而灵活的函数.真实惭愧啊! oracle的分析函数over ...

  6. 1.hive开窗函数,分析函数

    http://yugouai.iteye.com/blog/1908121 分析函数用于计算基于组的某种聚合值,它和聚合函数的不同之处是:对于每个组返回多行,而聚合函数对于每个组只返回一行.开窗函数指 ...

  7. oracle的分析函数over(Partition by...) 及开窗函数

        over(Partition by...) 一个超级牛皮的ORACLE特有函数. oracle的分析函数over 及开窗函数一:分析函数overOracle从8.1.6开始提供分析函数,分析函 ...

  8. sql server ,OVER(PARTITION BY)函数用法,开窗函数,over子句,over开窗函数

    https://technet.microsoft.com/zh-cn/library/ms189461(v=sql.105).aspx https://social.msdn.microsoft.c ...

  9. Gearman + Nodejs + MySQL UDF异步实现 MySQL 到 Redis 的数据同步

    [TOC] 1, 环境 CentOS, MySQL, Redis, Nodejs 2, Redis简介 Redis是一个开源的K-V内存数据库,它的key可以是string/set/hash/list ...

随机推荐

  1. c++ const enum #define

    最后的最后,我们略微总结一下:        1.只是声明单一固定值,尽可能采用const.        2.如果是一组固定值,并且互相有关联,则采用enum.        3.不涉及条件编译,只 ...

  2. SharePoint 2013 一次性上传文件大小限制

    默认是250MB,最大一次上传文件不超过2G The defaut size is 250MB and maximun upload size is 2047MB. It's can't greate ...

  3. There are inconsistent line endings in the 'xxx' script. Some are Mac OS X (UNIX) and some are Windows.问题解决

    在Window上使用Visual Studio编辑Unity3D脚本时常会出现类似如下警告: 警告 1 There are inconsistent line endings in the 'Asse ...

  4. VS 清除编译产生的临时文件、文件夹

    VS编译过程中会产生一些临时文件,通过以下脚本可清除 @echo off for /r %%i in (*.sdf,*.ncb,*.suo,*.exp,*.user,*.aps,*.idb,*.dep ...

  5. linux中,查看某个进程打开的文件数?

    需求描述: 今天在处理一个问题的时候,涉及到查看某个进程打开的文件数,在此记录下. 操作过程: 1.通过lsof命令查看某个特定的进程打开的文件数 [root@hadoop3 ~]# lsof -p ...

  6. C# Smtp方式发送邮件

    //简单邮件传输协议类             System.Net.Mail.SmtpClient client = new System.Net.Mail.SmtpClient();        ...

  7. 改善C#程序的建议5:引用类型赋值为null与加速垃圾回收

    http://www.cnblogs.com/luminji/archive/2011/04/07/2007205.html 在标准的Dispose模式中(见前一篇博客“C#中标准Dispose模式的 ...

  8. Maven------pom.xml自动加载各种类库代码

    转载: http://lavasoft.blog.51cto.com/62575/1388866/ 一般要加<type>jar</type> <dependency> ...

  9. 高级类特性----final关键字

    final 关键字 在Java中声明类.属性和方法时,可使用关键字final来修饰. final标记的变量(成员变量或局部变量)即成为常量,只能赋值一次. final标记的类不能被继承.提高安全性,提 ...

  10. python文件和目录操作方法大全(含实例)【python】

    转自:http://www.jb51.net/article/48001.htm 一.python中对文件.文件夹操作时经常用到的os模块和shutil模块常用方法. 1.得到当前工作目录,即当前Py ...