MYSQL-实现ORACLE- row_number() over(partition by ) 分组排序功能

  由于MYSQL没有提供类似ORACLE中OVER()这样丰富的分析函数. 所以在MYSQL里需要实现这样的功能,我们只能用一些灵活的办法:

1.首先我们来创建实例数据:

drop table if exists heyf_t10;
create table heyf_t10 (empid int ,deptid int ,salary decimal(10,2) ); insert into heyf_t10 values
(1,10,5500.00),
(2,10,4500.00),
(3,20,1900.00),
(4,20,4800.00),
(5,40,6500.00),
(6,40,14500.00),
(7,40,44500.00),
(8,50,6500.00),
(9,50,7500.00);

2. 确定需求: 根据部门来分组,显示各员工在部门里按薪水排名名次.

显示结果预期如下:

+-------+--------+----------+------+
| empid | deptid | salary | rank |
+-------+--------+----------+------+
| 1 | 10 | 5500.00 | 1 |
| 2 | 10 | 4500.00 | 2 |
| 4 | 20 | 4800.00 | 1 |
| 3 | 20 | 1900.00 | 2 |
| 7 | 40 | 44500.00 | 1 |
| 6 | 40 | 14500.00 | 2 |
| 5 | 40 | 6500.00 | 3 |
| 9 | 50 | 7500.00 | 1 |
| 8 | 50 | 6500.00 | 2 |
+-------+--------+----------+------+
9 rows in set (0.00 sec)

3. SQL 实现

SELECT
empid,
deptid,
salary,
rank
FROM
(
SELECT
empid,
deptid,
salary, IF (
@pdept = src.deptid ,@rank := @rank + 1 ,@rank := 1
) AS rank,
@pdept := src.deptid AS g
FROM
(
SELECT
empid,
deptid,
salary
FROM
heyf_t10
ORDER BY
deptid ASC,
salary DESC
) src,
(
SELECT
@pdept := NULL ,@rank := 0
) var
) z;

4. 结果演示

mysql> SELECT
-> empid,
-> deptid,
-> salary,
-> rank
-> FROM
-> (
-> SELECT
-> empid,
-> deptid,
-> salary,
->
-> IF (
-> @pdept = src.deptid ,@rank := @rank + 1 ,@rank := 1
-> ) AS rank,
-> @pdept := src.deptid AS g
-> FROM
-> (
-> SELECT
-> empid,
-> deptid,
-> salary
-> FROM
-> heyf_t10
-> ORDER BY
-> deptid ASC,
-> salary DESC
-> ) src,
-> (
-> SELECT
-> @pdept := NULL ,@rank := 0
-> ) var
-> ) z;
+-------+--------+----------+------+
| empid | deptid | salary | rank |
+-------+--------+----------+------+
| 1 | 10 | 5500.00 | 1 |
| 2 | 10 | 4500.00 | 2 |
| 4 | 20 | 4800.00 | 1 |
| 3 | 20 | 1900.00 | 2 |
| 7 | 40 | 44500.00 | 1 |
| 6 | 40 | 14500.00 | 2 |
| 5 | 40 | 6500.00 | 3 |
| 9 | 50 | 7500.00 | 1 |
| 8 | 50 | 6500.00 | 2 |
+-------+--------+----------+------+
9 rows in set (0.00 sec)

我的SQL:

SELECT
MESSAGE_ID,
GET_USER_ID,
SEND_USER_ID,
MESSAGE_CONTEXT,
CREATE_TIME
FROM
(
SELECT
SRC.*,
IF (
@V_USER_ID = USER_ID ,@V_RANK := @V_RANK + 1 ,@V_RANK := 1
) AS RANK ,@V_USER_ID := USER_ID AS G_USER_ID
FROM
(
SELECT
MESSAGE_ID,
USER_ID,
CREATE_TIME,
MESSAGE_CONTEXT,
GET_USER_ID,
SEND_USER_ID
FROM
(
SELECT
MESSAGE_ID,
GET_USER_ID,
SEND_USER_ID,
GET_USER_ID AS USER_ID,
CREATE_TIME,
MESSAGE_CONTEXT
FROM
T_SD_MESSAGE
WHERE
GET_USER_ID != ''
UNION ALL
SELECT
MESSAGE_ID,
GET_USER_ID,
SEND_USER_ID,
SEND_USER_ID AS USER_ID,
CREATE_TIME,
MESSAGE_CONTEXT
FROM
T_SD_MESSAGE
WHERE
SEND_USER_ID != ''
) METADATA
ORDER BY
USER_ID ASC,
CREATE_TIME DESC
) SRC,
(
SELECT
@V_RANK = 0,
@V_USER_ID := NULL
) VARS
) SRC
WHERE
RANK = 1
ORDER BY
CREATE_TIME DESC

一个过程;

DROP PROCEDURE
IF EXISTS PROCE_USER_NEW_MSG; DROP TEMPORARY TABLE
IF EXISTS TEM_USER_NEW_MSG;
DELIMITER || CREATE PROCEDURE PROCE_USER_NEW_MSG (
IN FRIST_RESULT INT,
IN FETCH_SIZE INT
)
BEGIN
SELECT
M.MESSAGE_ID,
M.GET_USER_ID,
M.SEND_USER_ID,
M.MESSAGE_CONTEXT,
M.CREATE_TIME,
G_U.USER_NAME AS G_USER_NAME,
S_U.USER_NAME AS S_USER_NAME,
G_H.GENERAL_PIC_THUMBNAIL_URL AS G_HEADER,
S_H.GENERAL_PIC_THUMBNAIL_URL AS S_HEADER
FROM
T_SD_MESSAGE M
LEFT JOIN T_SD_USER G_U ON M.GET_USER_ID = G_U.USER_ID
LEFT JOIN T_SD_USER S_U ON M.SEND_USER_ID = S_U.USER_ID
LEFT JOIN T_SD_GENERAL_PICTURE G_H ON G_H.GENERAL_PICTURE_ID = G_U.USER_HEADER_PIC_ID
LEFT JOIN T_SD_GENERAL_PICTURE S_H ON S_H.GENERAL_PICTURE_ID = S_U.USER_HEADER_PIC_ID
WHERE
M.MESSAGE_ID IN (
SELECT
MESSAGE_ID
FROM
(
SELECT
MESSAGE_ID,
RANK,
MESSAGE_CONTEXT,
CREATE_TIME
FROM
(
SELECT
SRC.*,
IF (
@V_USER_ID = USER_ID ,@V_RANK := @V_RANK + 1 ,@V_RANK := 1
) AS RANK ,@V_USER_ID := USER_ID AS G_USER_ID
FROM
(
SELECT
MESSAGE_ID,
USER_ID,
CREATE_TIME,
MESSAGE_CONTEXT,
GET_USER_ID,
SEND_USER_ID
FROM
(
SELECT
MESSAGE_ID,
GET_USER_ID,
SEND_USER_ID,
GET_USER_ID AS USER_ID,
CREATE_TIME,
MESSAGE_CONTEXT
FROM
T_SD_MESSAGE
WHERE
GET_USER_ID != ''
UNION ALL
SELECT
MESSAGE_ID,
GET_USER_ID,
SEND_USER_ID,
SEND_USER_ID AS USER_ID,
CREATE_TIME,
MESSAGE_CONTEXT
FROM
T_SD_MESSAGE
WHERE
SEND_USER_ID != ''
) METADATA
ORDER BY
USER_ID ASC,
CREATE_TIME DESC
) SRC,
(
SELECT
@V_RANK = 0,
@V_USER_ID := NULL
) VARS
) SRC
WHERE
RANK = 1
ORDER BY
CREATE_TIME DESC
) SRC
)
ORDER BY
M.CREATE_TIME DESC
LIMIT FRIST_RESULT,
FETCH_SIZE ;
END||
DELIMITER ; -- LIMIT FRIST_RESULT ,FETCH_SIZE
CALL PROCE_USER_NEW_MSG (0, 2);

转自:  http://ace105.blog.51cto.com/639741/724411

MYSQL-实现ORACLE- row_number() over(partition by ) 分组排序功能的更多相关文章

  1. MYSQL-实现分组排序 对比 ORACLE 和SQLserver用 row_number() over(partition by ) 分组排序功能

    以下是个人笔记: 本文是为了理解 row_number() over(partition by )  和实现各种数据库的分组排序功能 select ROW_NUMBER()over( partitio ...

  2. MYSQL-实现ORACLE 和SQLserver数据中- row_number() over(partition by ) 分组排序功能

    网上看见了好多例子都基本上是一样的,没有过多的解释,对于一个初学MySQL来说有点难,我把部分转摘过来如下 原文:http://www.cnblogs.com/buro79xxd/archive/20 ...

  3. oracle ROW_NUMBER() OVER(PARTITION BY '分组' ORDER BY '排序' DESC) 用法

    转载:https://blog.csdn.net/dbagaoshou/article/details/51330829 SELECT * FROM ( SELECT ROW_NUMBER() OVE ...

  4. hive:数据库“行专列”操作---使用collect_set/collect_list/collect_all & row_number()over(partition by 分组字段 [order by 排序字段])

    方案一:请参考<数据库“行专列”操作---使用row_number()over(partition by 分组字段 [order by 排序字段])>,该方案是sqlserver,orac ...

  5. oracle row_number() over(partition by .. order by ..)和rank() over(partition by .. order by ..) 和dense_rank() over(partition by .. order by ..)的相似点与区别

    新建一个测试表 create table dim_ia_test2(device_number varchar2(20),desc2 varchar2(20)) 插入数据后得到: 一.oracle r ...

  6. sql 分组取最新的数据sqlserver巧用row_number和partition by分组取top数据

    SQL Server 2005后之后,引入了row_number()函数,row_number()函数的分组排序功能使这种操作变得非常简单 分组取TOP数据是T-SQL中的常用查询, 如学生信息管理系 ...

  7. row_number和partition by分组取top数据

    分组取TOP数据是T-SQL中的常用查询, 如学生信息管理系统中取出每个学科前3名的学生.这种查询在SQL Server 2005之前,写起来很繁琐,需要用到临时表关联查询才能取到.SQL Serve ...

  8. 去重 ROW_NUMBER() OVER(PARTITION BY 分组字段 ORDER BY 排序字段) RN

    关键字  ROW_NUMBER() OVER(PARTITION BY 分组字段 ORDER BY 排序字段) RN 按照分组字段进行排序并标编号 ROW_NUMBER() OVER(PARTITIO ...

  9. row_number() over partition by 分组聚合

    分组聚合,就是先分组再排序,可以的话顺手标个排名:如果不想分组也可以排名:如果不想分组同时再去重排名也可以 ROW_NUMBER() OVER( [PARTITION BY column_1, col ...

随机推荐

  1. Part 45 to 47 Talking about Enums in C#

    Part 45   C# Tutorial   Why Enums Enums are strongly typed constants. If a program uses set of integ ...

  2. table-layout:fixed 属性的解说

    table-layout:fixed 属性的解说如果想要一个table固定大小,里面的文字强制换行(尤其是在一长串英文文本,并且中间无空格分隔的情况下),以达到使过长的文字不撑破表格的目的,一般是使用 ...

  3. Linux命令(2):ls命令

    1.作用:列出目录的内容: 2.格式:ls [选项] [文件] [选项]为指定要查看文件相关的内容,若未指定文件默认查看当前目录下的所有文件: 3.常见参数: 如图: 4.使用实例: [yournam ...

  4. centOS6.5x64简单的安装openfire

    yum install java libldb.i686 mysql-server mysql-connector-java 创建数据库 create database openfire defaul ...

  5. php数组编码转换函数的示例

    场景说明/问题描述: Ajax提交页面编码为gb2312,数据库编码为utf8,在不更改页面及数据库编码的情况下插入数据. 自定义函数:  代码如下 复制代码 function array_iconv ...

  6. php 检查email电子邮件函数(奇葩写法)

    以前写的一个PHP表单电子邮件发送程序,其中采用如下方法来验证电子邮件地址格式是否正确: 代码如下 复制代码 eregi("^[_a-z0-9-]+(.[_a-z0-9-]+)*@[a-z0 ...

  7. 集合类学习之ArrayList源码解析

    1.概述 ArrayList是List接口的可变数组的实现.实现了所有可选列表操作,并允许包括 null 在内的所有元素.除了实现 List 接口外,此类还提供一些方法来操作内部用来存储列表的数组的大 ...

  8. 【Unity3D实战】摇摆直升机开发实战(一)

    [Unity3D实战]摇摆直升机开发实战(一) 1.点击[Assets],创建[Sprites]和[Resources]文件夹,然后将所需要的素材导入[Sprites]文件夹中. 2.找到[Sprit ...

  9. Optimistic Offline Lock乐观离线锁

    通过冲突检测和(发生冲突时的)事务回滚,来防止并发业务事务中的冲突. 通常一个业务事务的执行,会跨越一系列的系统事务. 一旦超出了单个系统事务的范围,就不能仅依靠DB管理程序来保证数据一致性. 乐观离 ...

  10. 4月12日学习笔记——jQuery操作属性和样式

    区分 DOM 属性和元素属性 <img src="images/image.1.jpg" id="hibiscus" alt="Hibiscus ...