MySQL实现SQL Server排名函数

最近在MySQL中遇到分组排序查询时,突然发现MySQL中没有row_number() over(partition by colname)这样的分组排序。
并且由于MySQL中没有类似于SQL Server中的row_number()、rank()、dense_rank()等排名函数,所有找到以下实现方法,在此简单记录一下。

首先创建一个表并插入测试数据。

create table demo.Student (
   ID int(11) NOT NULL AUTO_INCREMENT,
   StuNo varchar(32) NOT NULL,
   StuName varchar(10) NOT NULL,
   StuAge int(11) DEFAULT NULL,
   PRIMARY KEY (ID)
 )
 engine=innodb auto_increment=1 default charset=utf8 collate=utf8_general_ci;

insert into demo.Student(StuNo,StuName,StuAge) values(‘A001‘,‘小明‘,22);
insert into demo.Student(StuNo,StuName,StuAge) values(‘A005‘,‘小李‘,23);
insert into demo.Student(StuNo,StuName,StuAge) values(‘A007‘,‘小红‘,24);
insert into demo.Student(StuNo,StuName,StuAge) values(‘A003‘,‘小明‘,22);
insert into demo.Student(StuNo,StuName,StuAge) values(‘A002‘,‘小李‘,23);
insert into demo.Student(StuNo,StuName,StuAge) values(‘A004‘,‘小红‘,24);
insert into demo.Student(StuNo,StuName,StuAge) values(‘A006‘,‘小王‘,25);

select * from demo.Student;

测试数据如下:

实现row_number()排名函数,按学号(StuNo)排序。

-- @row_number:=0,设置变量@row_number的初始值为0。
-- @row_number:[email protected]_number+1,累加@row_number的值。
select ID,StuNo,StuName,StuAge,@row_number:[email protected]_number+1 as row_number
from demo.Student a,
(
    select @row_number:=0
) b
order by StuNo asc;

结果如下:

实现rank()排名函数,按学生年龄(StuAge)排序。

-- @StuAge:=null,设置变量@StuAge的初始值为null
-- @rank:=0,设置变量@rank的初始值为0
-- @inRank:=1,设置变量@inRank的初始值为1
-- if(@StuAge=StuAge,@rank,@rank:[email protected]),指定排序列的值不变时,@rank的值不变;指定排序列的值变化时,@rank的值跳变为@inRank内部计数的值
-- @inRank:[email protected]+1,每一行自增1,用于实现内部计数
select t.ID,t.StuNo,t.StuName,t.StuAge,t.row_rank
from
(
    select ID,StuNo,StuName,StuAge,if(@StuAge=StuAge,@rank,@rank:[email protected]) as row_rank,@inRank:[email protected]+1,@StuAge:=StuAge
    from demo.Student a,
    (
        select @StuAge:=null,@rank:=0,@inRank:=1
    ) b
    order by StuAge asc
) t;

结果如下:

实现dense_rank()排名函数,按学生年龄(StuAge)排序。

-- @StuAge:=null,设置变量@StuAge的初始值为null
-- @rank:=0,设置变量@rank的初始值为0
-- if(@StuAge=StuAge,@rank,@rank:[email protected]+1),指定排序列的值不变时,@rank的值不变;指定排序列的值变化时,@rank的值自增1
select t.ID,t.StuNo,t.StuName,t.StuAge,t.row_rank
from
(
    select ID,StuNo,StuName,StuAge,if(@StuAge=StuAge,@rank,@rank:[email protected]+1) as row_rank,@StuAge:=StuAge
    from demo.Student a,
    (
        select @StuAge:=null,@rank:=0
    ) b
    order by StuAge asc
) t;

结果如下:

实现row_number() over(partition by colname order by colname)分组排名函数,按学生年龄(StuAge)分组排序。

-- @StuAge:=null,设置变量@StuAge的初始值为null
-- @row_number:=0,设置变量@row_number的初始值为0
-- if(@StuAge=StuAge,@row_number:[email protected]_number+1,@row_number:=1),指定排序列的值不变时,@row_number的值自增1;指定排序列的值变化时,@row_number的值等于1
select t.ID,t.StuNo,t.StuName,t.StuAge,t.row_number
from
(
    select ID,StuNo,StuName,StuAge,if(@StuAge=StuAge,@row_number:[email protected]_number+1,@row_number:=1) as row_number,@StuAge:=StuAge
    from demo.Student a,
    (
        select @StuAge:=null,@row_number:=0
    ) b
    order by StuAge asc
) t;

结果如下:

实现分组聚合字符串,即把指定列的值拼成字符串。
在SQL Server中时利用了中间变量实现,现在在MySQL中就比较简单了。
MySQL提供了一个group_concat()函数,可以把指定列的值拼成一个字符串,并可以按指定排序方式拼成字符,之间用逗号隔开。如下示例:

select group_concat(StuNo order by StuNo asc) as column1,group_concat(StuNo order by ID asc) as column2
from demo.Student 

结果如下:

select StuName,group_concat(StuNo order by StuNo asc) as column1,concat(‘"‘,group_concat(StuNo order by StuNo asc),‘"‘) as column2
from demo.Student
group by StuName
order by StuAge 

结果如下:

原文地址:https://www.cnblogs.com/asdyzh/p/9818761.html

时间: 2024-11-08 13:21:13

MySQL实现SQL Server排名函数的相关文章

SQL Server 排名函数

内容摘要: Transact-SQL提供了4个排名函数: RANK(),DENSE_RANK(),ROW_NUMBER(),NTILE(),下文是对这4个函数进行的解释. 下面是对这4个函数的解释: RANK() 返回结果集的分区内每行的排名.行的排名是相关行之前的排名数加一. 如果两个或多个行与一个排名关联,则每个关联行将得到相同的排名. 例如,如果两位销售员具有相同的SalesYTD值,则他们将并列第一.由于已有两行排名在前,所以具有下一个最大SalesYTD的销售人员将排名第三. 因此,R

sql server 排名函数:DENSE_RANK

一.需求 之前sql server 的排名函数用得最多的应该是RoW_NUMBER()了,我通常用ROW_NUMBER() + CTE 来实现分页:今天逛园,看到另一个内置排名函数还不错,自己顺便想了一个需求,大家可以花1分钟先想想要怎么实现. 需求很简单:求成绩排名前五的学生信息. 例如: 由于成绩可以并列,所以前五名可能有多个.例如: 测试数据: declare @t table (ID int, StudentName nvarchar(15), Score int) insert int

SQL Server 排名函数实现

在SQL Server 中有四大排名函数分别是: 1.row_number() 2.ntile() 3.rank() 4.dense_rank() ------------------------------------------------------------------------- 为了方便演示我们先建立相关的表 create table t(ID int ,Name varchar(32));go insert into t(ID,Name) values(1,'A'),(2,'A

SQL Server排名函数与排名开窗函数

什么是排名函数?说实话我也不甚清楚,我知道 order by 是排序用的,那么什么又是排名函数呢? 接下来看几个示例就明白了. 首先建立一个表,随便插入一些数据. ROW_NUMBER 函数:直接排序,ROW_NUMBER函数是以上升进行直接排序,并且以连续的顺序给每一行数据一个唯一的序号.(即排名连续) 1 -- 以下是根据 U_Pwd 这一列进行排名(升序) 2 select *, 3 '第'+convert(varchar,ROW_NUMBER() over(order by U_Pwd)

SQL SERVER 开窗函数简介

在SQL SERVER 2005/2008支持两种排名开窗函数和聚集开窗函数. 以SQL SERVER中分面页为例,按时间顺序列出定单号. WITH OrderInfo AS ( SELECT ROW_NUMBER() OVER(ORDER BY OrderDate) AS Number, OrderID,CustomerID, EmployeeID,OrderDate FROM Orders (NOLOCK) ) SELECT Number,OrderID,CustomerID, Employ

数据库开发基础-SQl Server 聚合函数、数学函数、字符串函数、时间日期函数

SQL 拥有很多可用于计数和计算的内建函数. 函数的语法 内建 SQL 函数的语法是: SELECT function(列) FROM 表 函数的类型 在 SQL 中,基本的函数类型和种类有若干种.函数的基本类型是: Aggregate 函数 Scalar 函数 合计函数(Aggregate functions) Aggregate 函数的操作面向一系列的值,并返回一个单一的值. 注释:如果在 SELECT 语句的项目列表中的众多其它表达式中使用 SELECT 语句,则这个 SELECT 必须使

SQL SERVER开窗函数

SQL SERVER开窗函数 总结的很好,转来做个笔记. 转自:http://www.cnblogs.com/csdbfans/p/3504845.html 今天将要介绍SQL Sever的开窗函数,何谓开窗函数,不懂吧.反正对于我来说,我是摸不着头脑了,第一次听说过.那么,什么是开窗函数,其实可以理解为是聚合函数的一个加强版.因为使用聚合函数的话(不包括子查询的情况),整个查询都只能是聚合列返回值,而不能有基础行的返回值.那么对于需要基础行的返回值的话,就需要使用复杂的子查询或者是存储过程等才

SQL Server DATEDIFF() 函数

Server Date 函数 定义和用法 DATEDIFF() 函数返回两个日期之间的天数. 语法DATEDIFF(datepart,startdate,enddate) startdate 和 enddate 参数是合法的日期表达式. datepart 参数可以是下列的值: datepart 缩写 年 yy, yyyy 季度 qq, q 月 mm, m 年中的日 dy, y 日 dd, d 周 wk, ww 星期 dw, w 小时 hh 分钟 mi, n 秒 ss, s 毫秒 ms 微妙 mc

SQL Server 聚合函数算法优化技巧

Sql server聚合函数在实际工作中应对各种需求使用的还是很广泛的,对于聚合函数的优化自然也就成为了一个重点,一个程序优化的好不好直接决定了这个程序的声明周期.Sql server聚合函数对一组值执行计算并返回单一的值.聚合函数对一组值执行计算,并返回单个值.除了 COUNT 以外,聚合函数都会忽略空值. 聚合函数经常与 SELECT 语句的 GROUP BY 子句一起使用. v1.写在前面 如果有对Sql server聚合函数不熟或者忘记了的可以看我之前的一片博客.sql server 基