在操作sql 查询数据的时候有时候会遇到查询每一个用户第一次干嘛或者第几次干嘛的数据,这个时候往往第一想到的是group by,这边介绍一种不采用group by的实现方式,首先介绍一下我的表和数据:
CREATE TABLE `orderTable` (
`num` int(11) DEFAULT NULL, --数据id
`userId` varchar(255) DEFAULT NULL, -- 用户id
`name` varchar(255) DEFAULT NULL, --用户名称
`time` datetime DEFAULT NULL, --时间
`tag` int(3) DEFAULT '0' --标记(验证查询数据结果正确性)
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_0900_ai_ci
和表内的数据
INSERT INTO `orderTable` VALUES (1, '001', 'u001', '2019-06-08 21:48:54', 1);
INSERT INTO `orderTable` VALUES (2, '001', 'u001', '2019-06-29 21:49:16', 2);
INSERT INTO `orderTable` VALUES (3, '002', 'u002', '2019-06-06 21:49:38', 1);
INSERT INTO `orderTable` VALUES (4, '001', 'u001', '2019-06-30 21:49:58', 3);
INSERT INTO `orderTable` VALUES (5, '002', 'u002', '2019-06-30 21:50:21', 2);
INSERT INTO `orderTable` VALUES (6, '003', 'u003', '2019-06-03 21:50:50', 1);
INSERT INTO `orderTable` VALUES (7, '003', 'u003', '2019-06-05 21:51:06', 2);
INSERT INTO `orderTable` VALUES (8, '004', 'u004', '2019-06-20 21:51:26', 1);
INSERT INTO `orderTable` VALUES (9, '001', 'u001', '2019-07-02 21:53:06', 4);
现在要查找出每一个用户的第二次交易的数据
select t.*
from (
select
if(@last = t.userId, @gnum, @gnum := @gnum + 1) as gnum,
if(@last <> t.userId, @rnum := 1, @rnum := @rnum + 1) as rnum,
@last := t.userId,
'||',
t.*
from
(select @gnum := 0, @rnum := 1, @last := '') p,
orderTable t
ORDER BY t.userId, t.time
) t
where t.rnum = 2
原理是通过ORDER BY对数userId和time进行排序,再为每行数据添加上gnum(group number)和group内rnum(row number),再结合通过这两个编号进行数据过滤。
网友评论