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. Android OpenGL ES(三)----编程框架

    首先当然是创建Android项目,你可以选择最新的Android Studio也可以选择eclipse都是一样的.我们重点讲解开发OpenGL ES的流程 1.定义顶点着色器和片段着色器 第一节我们讲 ...

  2. jQuery插件的编写和使用 <思维导图>

    以下是jQuery插件的编写和使用的思维导图,全屏观看,请点击:jQuery插件的编写和使用

  3. sql_查询select

    sql_查询select   /****** Script for SelectTopNRows command from SSMS ******/ [r_gonghao] ,[r_mingzi] , ...

  4. [转]Mac OS X 下部分Android手机无法连接adb问题之解决方案

    时至当今,Android山寨手机厂商已如此之多,能修改和个性化定制Android OS的能人已是多如牛毛,有的牛人修改Android系统只会影响所修改的点,不会影响其它,然后还有的就不多说了,总之做的 ...

  5. 将slider滑块从横着变为竖着的时候坐标变换的计算

    ////  ViewController.m//  imageview添加按钮////  Created by hehe on 15/9/22.//  Copyright (c) 2015年 wang ...

  6. VxWorks 6.9 内核编程指导之读书笔记 -- 多任务

    概述 VxWork系统任务 任务调度 任务创建和管理 任务的错误状态 任务异常处理 共享代码和重入 概述 现代实时操作系统是基于多任务和任务间通信的概念的.多任务环境运行一个实时进程RTP可以被作为一 ...

  7. Java并发编程概要

    线程开的越多,则性能越好吗? 未必,影响多线程性能的因素有:上下文切换,竞争/死锁,资源限制等.对于这些因素要均衡考量,才能获得较好的性能. 并发控制/线程间的通信方式 基本的并发控制原语有 vola ...

  8. python——类

    类的定义格式: class CLASSNAME(父类1,父类2,父类3): __A  = 0     ##私有属性,两个_开头,只有在该类中的函数才能访问 B = 0 ##公共属性 def 函数名(s ...

  9. 看部电影,透透彻彻理解IoC(你没有理由再迷惑!)

    引述:IoC(控制反转:Inverse of Control)是Spring容器的内核,AOP.声明式事务等功能在此基础上开花结果.但是IoC这个重要的概念却比较晦涩隐讳,不容易让人望文生义,这不能不 ...

  10. 如何判断PHP 是ts还是nts版的

    通过phpinfo(); 查看其中的 Thread Safety 项,这个项目就是查看是否是线程安全,如果是:enabled,一般来说应该是ts版,否则是nts版.