Mysql案例
- 1.分组查询排名优先的数据
- 1.1 分组获取最新一条记录
- 1.2 分组获取最新的两条数据
1.分组查询排名优先的数据
-- ----------------------------
-- Table structure for user
-- ----------------------------
DROP TABLE IF EXISTS `user`;
CREATE TABLE `user` (
`id` int(11) NOT NULL AUTO_INCREMENT,
`username` varchar(255) DEFAULT NULL,
`create_time` datetime DEFAULT CURRENT_TIMESTAMP,
PRIMARY KEY (`id`)
) ENGINE=InnoDB AUTO_INCREMENT=6 DEFAULT CHARSET=utf8;
-- ----------------------------
-- Records of user
-- ----------------------------
INSERT INTO `user` VALUES ('1', 'jack', '2020-03-21 16:55:07');
INSERT INTO `user` VALUES ('2', 'jack', '2020-03-21 16:55:18');
INSERT INTO `user` VALUES ('3', 'jack', '2020-03-21 16:55:25');
INSERT INTO `user` VALUES ('4', 'marry', '2020-03-21 16:55:33');
INSERT INTO `user` VALUES ('5', 'marry', '2020-03-21 16:55:37');
1.1 分组获取最新一条记录
一、使用left join实现
SELECT u1.*,u2.*
FROM `user` u1 LEFT JOIN `user` u2
ON (u1.username = u2.username AND u1.create_time < u2.create_time)
WHERE u2.id is NULL;
方法分析
1.首先来看,不加u1.create_time < u2.create_time
和where条件,查询结果为笛卡尔积
2.然后,加上u1.create_time < u2.create_time
条件后,就会过滤一部分数据剩下的数据特征是:左侧<右侧
3.左侧数据中, 每个username都有一条最大的create_time, 它是无法匹配到右侧数据
, 所以右侧数据为null, 这条数据, 恰恰是我们想要的那条数据
此时数据为:
4.最后,右侧为null的即为create_time最大(即最新插入的数据),所以加上WHERE u2.id is NULL
后查询结果为:
二、使用rank()实现
select * from
(
select RANK() over(partition by username order by create_time desc) rk, u.* FROM `user` u
) t
where t.rk = 1
1.2 分组获取最新的两条数据
select * from
(
select RANK() over(partition by username order by create_time desc) rk, u.* FROM `user` u
) t
where t.rk <= 2