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. SQL数据库开发知识总结:基础篇

    1数据库概述 (1) 用自定义文件格式保存数据的劣势. (2) DBMS(DataBase Management System,数据库管理系统)和数据库,平时谈到”数据库”可能有两种含义:MSSQL ...

  2. git 基本使用

    简单几步操作让你在终端下用git实现文件的上传. 一.克隆项目    在工作中,常见的情景都是远程库已经建好了,需要大家把代码拉下来,共同协作开发.本文所有操作均在终端下进行.    //克隆一个本地 ...

  3. 转载:简单介绍Python中的try和finally和with方法

    用 Python 做一件很平常的事情: 打开文件, 逐行读入, 最后关掉文件; 进一步的需求是, 这也许是程序中一个可选的功能, 如果有任何问题, 比如文件无法打开, 或是读取出错, 那么在函数内需要 ...

  4. setbuf

    setbuf是linux中的C函数,主要用于打开和关闭缓冲机制. setbuf函数具有打开和关闭缓冲机制.为了带缓冲进行I/O,参数buf必须指向一个长度为BUFSIZ(定义在stdio.h头文件中) ...

  5. 《UNIX编程艺术》读书笔记

    最近这段时间比较忙,利用业余时间看完了这本书.虽然书中讲到的很多例子都是上古文物,我没有用过,不过原理都是相通的,对我的启发很大.比如无所不在的KISS原则,实践中慢慢体会到的SPOT原则,无不产生共 ...

  6. 在Java中怎样把数组转换为ArrayList?

    翻译自:How to Convert Array to ArrayList in Java? 本文分析了Stack Overflow上最热门的的一个问题的答案,提问者获得了很多声望点,使得他得到了在S ...

  7. Windows Phone 8.1开发:如何让ListView滚动到顶部,回到第一条?

    Windows Phone 8.1开发中,ListView向下滑动了半天,用户如果突然想回头看看第一条数据怎么办? 如何让listView滚动到顶部,回到第一条? 很简单,一行代码.调用ListVie ...

  8. 处理jquery版本之间冲突

    处理jquery版本之间冲突 前端开发们都知道jquery版本有好多,之间冲突很纠结.比如我刚来这公司的时候,后端的哥们用的是jQuery 1.3.2,我了个去,那哥们好久没更新了.我写的效果插件都是 ...

  9. Abstract_Factory

    #include <iostream> using namespace std; #define DESTORY_POINTER(ptr) if (ptr) { delete ptr; p ...

  10. 可以支持jQuery1.10.1 的 fancybox 1.3.4, 並現在type為Ajax時,也可以定義窗口的大小。

    官網上的 fancybox 1.3.4 太老了,不支持jQuery1.10.1,改動了一下源碼,現在可以支持了. type為Ajax時,也可以定義窗口的大小. $("#ajaxlink&qu ...