mysql实现分组排序

群里有童鞋问,想要根据用户分组,以该用户的下单时间为降序,提取所有用户的第二个订单信息。

这属于分组排序,在Oracle有内置函数可以实现,而在mysql,做起来比较蛋疼。

我提供一种方法供参考

CREATE TABLE user_orders (orders_id INT UNSIGNED NOT NULL,
user_id INT UNSIGNED NOT NULL,
add_time INT UNSIGNED NOT NULL,
PRIMARY KEY(orders_id),
KEY(user_id),
KEY(add_time)
)ENGINE=INNODB DEFAULT CHARSET utf8 COMMENT ‘mysql实现分组排序测试表‘;

INSERT INTO `user_orders` (`orders_id`, `user_id`, `add_time`) VALUES(‘1‘,‘1‘,‘1‘);
INSERT INTO `user_orders` (`orders_id`, `user_id`, `add_time`) VALUES(‘2‘,‘1‘,‘2‘);
INSERT INTO `user_orders` (`orders_id`, `user_id`, `add_time`) VALUES(‘3‘,‘1‘,‘3‘);
INSERT INTO `user_orders` (`orders_id`, `user_id`, `add_time`) VALUES(‘4‘,‘2‘,‘1‘);
INSERT INTO `user_orders` (`orders_id`, `user_id`, `add_time`) VALUES(‘5‘,‘2‘,‘2‘);
INSERT INTO `user_orders` (`orders_id`, `user_id`, `add_time`) VALUES(‘6‘,‘2‘,‘3‘);
INSERT INTO `user_orders` (`orders_id`, `user_id`, `add_time`) VALUES(‘7‘,‘3‘,‘1‘);
INSERT INTO `user_orders` (`orders_id`, `user_id`, `add_time`) VALUES(‘8‘,‘3‘,‘2‘);
INSERT INTO `user_orders` (`orders_id`, `user_id`, `add_time`) VALUES(‘9‘,‘3‘,‘3‘);

SELECT orders_id,user_id,add_time,rank FROM (
SELECT  @rownum:[email protected]+1 AS rownum,# 行号
    IF(@x=uo.user_id,@rank:[email protected]+1,@rank:=1) rank,#处理排名,如果@x等于user_id,则表示@x被初始化,将@rank自增1
    @x:=uo.user_id, # 初始化@x,@x为中间变量,在rank之后初始化,所以,rank初始化时,@x为null或者是上一个user_id的值
    orders_id,user_id,add_time 
FROM  
    user_orders  uo,
    (SELECT @rownum:=0,@rank:=0) init # 初始化信息表
ORDER BY user_id ASC, add_time DESC
)result
WHERE rank=2

重点:关键在于@x如何赋值。了解@x的赋值之后,立马就能明白rank(名次)的由来。

时间: 2024-08-25 02:39:15

mysql实现分组排序的相关文章

MySQL高级分组排序

想要根据用户分组,以该用户的下单时间为降序,提取所有用户的第二个订单信息.这属于分组排序,在Oracle有内置函数可以实现,而在mysql就有点麻烦: CREATE TABLE user_orders (orders_id INT UNSIGNED NOT NULL, user_id INT UNSIGNED NOT NULL, add_time INT UNSIGNED NOT NULL, PRIMARY KEY(orders_id), KEY(user_id), KEY(add_time)

MySql 分组排序取时间最大的一条记录

SELECT A.* FROM digital_asset A, (SELECT name, max(last_updated) max_day FROM digital_asset GROUP BY name) B WHERE A.name = B.name AND A.last_updated = B.max_day SELECT A . * FROM bbs_threads A, ( SELECT digest, max( dateline ) max_dateline FROM bbs_

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

网上看见了好多例子都基本上是一样的,没有过多的解释,对于一个初学MySQL来说有点难,我把部分转摘过来如下 原文:http://www.cnblogs.com/buro79xxd/archive/2012/08/29/2662489.html 要求目标:1.确定需求: 根据部门来分组,显示各员工在部门里按薪水排名名次. 创建表格:2.来创建实例数据: drop table if exists heyf_t10; create table heyf_t10 (empid int ,deptid i

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 i

Mysql 数据分组取某字段值所有最大的记录行

需求: 表中同一个uid(用户)拥有多条游戏等级记录,现需要取所有用户最高等级(level)的那一条数据,且时间(time)越早排越前.这是典型的排名表 +------+-------+--------------+---------------------+ | uid | level | role | time | +------+-------+--------------+---------------------+ | 7 | 1 | 摇滚圣魔 | 2014-06-12 15:01:0

MySQL 对分组后的同类数据进行拼接字符串

MySQL 对分组后的同类数据进行拼接字符串 写后台方法时遇到个问题,需要将表内同一订单号的操作记录流水进行简单拼接输出,不想取出来再操作,找了个mysql的方法直接操作 group_concat对组内的每一行数据拼接,内部可以排序.使用separator 进行分割 concat_ws对一行内的各个字段进行拼接,第一项指定分隔符,后续的有null会忽略 select oid, group_concat(concat_ws('|',atime,(select `level` from prizes

本地化下按首字母分组排序的神器——UILocalizedIndexedCollation

最近在整一个很简单的通讯录相关的项目,通讯录当然就少不了按首字母或者汉字拼音首字母分组排序索引.因为按照我一贯的的做法,都是想要做成更通用的.支持本地化的,所以这就纠结了,世界各地的语言啊我去,我顶多也就认识中文和英语,这就不能用以前的那些比如把汉字转成拼音再排序的方法了,效率不高不说,对其他国家的本地化更是行不通.一个偶然的机会,我才发现SDK里已经提供了一个实现此功能的神器——UILocalizedIndexedCollation. 首先提一下,UILocalizedIndexedColla

sql server 中判断分组排序的使用示例

现在需要查询一组数据,是对一列字段(column01)的数据分范围查询后分组排序: select (case when [column01] >0 AND [column01]<= 500 THEN 1 when [column01] >500 AND [column01]<= 1000 THEN 2 when [column01] >1000 AND [column01]<= 5000 THEN 3 when [column01] >5000 AND [colu

对数据库表中的某一字段去重分组排序

1.问题背景    某数据库t_tab_ab中有两个字段a和b,如下所示:    查询前:                 查询后:    a     b                  a     b    1     2                  1     2    1     3                  2     3    1     4                  3     4    1     5    2     3    2     4    2