MYSQL-实现ORACLE- row_number() over(partition by ) 分组排序功能
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 ) 分组排序功能的更多相关文章
- MYSQL-实现分组排序 对比 ORACLE 和SQLserver用 row_number() over(partition by ) 分组排序功能
以下是个人笔记: 本文是为了理解 row_number() over(partition by ) 和实现各种数据库的分组排序功能 select ROW_NUMBER()over( partitio ...
- MYSQL-实现ORACLE 和SQLserver数据中- row_number() over(partition by ) 分组排序功能
网上看见了好多例子都基本上是一样的,没有过多的解释,对于一个初学MySQL来说有点难,我把部分转摘过来如下 原文:http://www.cnblogs.com/buro79xxd/archive/20 ...
- oracle ROW_NUMBER() OVER(PARTITION BY '分组' ORDER BY '排序' DESC) 用法
转载:https://blog.csdn.net/dbagaoshou/article/details/51330829 SELECT * FROM ( SELECT ROW_NUMBER() OVE ...
- hive:数据库“行专列”操作---使用collect_set/collect_list/collect_all & row_number()over(partition by 分组字段 [order by 排序字段])
方案一:请参考<数据库“行专列”操作---使用row_number()over(partition by 分组字段 [order by 排序字段])>,该方案是sqlserver,orac ...
- 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 ...
- sql 分组取最新的数据sqlserver巧用row_number和partition by分组取top数据
SQL Server 2005后之后,引入了row_number()函数,row_number()函数的分组排序功能使这种操作变得非常简单 分组取TOP数据是T-SQL中的常用查询, 如学生信息管理系 ...
- row_number和partition by分组取top数据
分组取TOP数据是T-SQL中的常用查询, 如学生信息管理系统中取出每个学科前3名的学生.这种查询在SQL Server 2005之前,写起来很繁琐,需要用到临时表关联查询才能取到.SQL Serve ...
- 去重 ROW_NUMBER() OVER(PARTITION BY 分组字段 ORDER BY 排序字段) RN
关键字 ROW_NUMBER() OVER(PARTITION BY 分组字段 ORDER BY 排序字段) RN 按照分组字段进行排序并标编号 ROW_NUMBER() OVER(PARTITIO ...
- row_number() over partition by 分组聚合
分组聚合,就是先分组再排序,可以的话顺手标个排名:如果不想分组也可以排名:如果不想分组同时再去重排名也可以 ROW_NUMBER() OVER( [PARTITION BY column_1, col ...
随机推荐
- Android OpenGL ES(三)----编程框架
首先当然是创建Android项目,你可以选择最新的Android Studio也可以选择eclipse都是一样的.我们重点讲解开发OpenGL ES的流程 1.定义顶点着色器和片段着色器 第一节我们讲 ...
- jQuery插件的编写和使用 <思维导图>
以下是jQuery插件的编写和使用的思维导图,全屏观看,请点击:jQuery插件的编写和使用
- sql_查询select
sql_查询select /****** Script for SelectTopNRows command from SSMS ******/ [r_gonghao] ,[r_mingzi] , ...
- [转]Mac OS X 下部分Android手机无法连接adb问题之解决方案
时至当今,Android山寨手机厂商已如此之多,能修改和个性化定制Android OS的能人已是多如牛毛,有的牛人修改Android系统只会影响所修改的点,不会影响其它,然后还有的就不多说了,总之做的 ...
- 将slider滑块从横着变为竖着的时候坐标变换的计算
//// ViewController.m// imageview添加按钮//// Created by hehe on 15/9/22.// Copyright (c) 2015年 wang ...
- VxWorks 6.9 内核编程指导之读书笔记 -- 多任务
概述 VxWork系统任务 任务调度 任务创建和管理 任务的错误状态 任务异常处理 共享代码和重入 概述 现代实时操作系统是基于多任务和任务间通信的概念的.多任务环境运行一个实时进程RTP可以被作为一 ...
- Java并发编程概要
线程开的越多,则性能越好吗? 未必,影响多线程性能的因素有:上下文切换,竞争/死锁,资源限制等.对于这些因素要均衡考量,才能获得较好的性能. 并发控制/线程间的通信方式 基本的并发控制原语有 vola ...
- python——类
类的定义格式: class CLASSNAME(父类1,父类2,父类3): __A = 0 ##私有属性,两个_开头,只有在该类中的函数才能访问 B = 0 ##公共属性 def 函数名(s ...
- 看部电影,透透彻彻理解IoC(你没有理由再迷惑!)
引述:IoC(控制反转:Inverse of Control)是Spring容器的内核,AOP.声明式事务等功能在此基础上开花结果.但是IoC这个重要的概念却比较晦涩隐讳,不容易让人望文生义,这不能不 ...
- 如何判断PHP 是ts还是nts版的
通过phpinfo(); 查看其中的 Thread Safety 项,这个项目就是查看是否是线程安全,如果是:enabled,一般来说应该是ts版,否则是nts版.