MySQL-分组排序

1,040 阅读3分钟

场景

需求场景:有一批包含城市名称和城市的不同时间段的数据,需要筛选出在不同城市,每天时间最晚的那条记录,需要对城市名称、时间进行分组并倒序,筛选出时间最晚的那条

思路

考虑用GROUP BY或者开窗函数:OVER (PARTITION BY 分组字段 ORDER BY 排序字段),然而本地的数据库服务器环境为MySQL5.7,貌似 MySQL8 之后才支持 OVER。(其实是先用 GROUP BY 运行成功后,想用 PARTITION BY 优化来着,一直运行报错,有些资料里也没描述用的哪种数据库,反正 MySQL5.7 应该是不适用的)

数据表

## 1、建表
CREATE TABLE `show_data` (
  `id` int(11) NOT NULL COMMENT '主键',
  `show_time` datetime DEFAULT NULL,
  `name` varchar(255) DEFAULT NULL,
  `code` varchar(255) DEFAULT NULL,
  `create_time` datetime DEFAULT NULL,
  PRIMARY KEY (`id`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COMMENT='分组排序案例';

## 2、插入数据
INSERT INTO `show_data`(`id`, `show_time`, `name`, `code`, `create_time`) VALUES (1, '2021-12-01 19:23:13', '南昌', '南昌-1-1', '2021-12-06 19:23:36');
INSERT INTO `show_data`(`id`, `show_time`, `name`, `code`, `create_time`) VALUES (2, '2021-12-02 19:25:01', '南昌', '南昌-2-1', '2021-12-06 19:24:41');
INSERT INTO `show_data`(`id`, `show_time`, `name`, `code`, `create_time`) VALUES (3, '2021-12-03 19:25:06', '南昌', '南昌-3-1', '2021-12-06 19:24:45');
INSERT INTO `show_data`(`id`, `show_time`, `name`, `code`, `create_time`) VALUES (4, '2021-12-01 19:25:11', '赣州', '赣州-1-1', '2021-12-06 19:24:48');
INSERT INTO `show_data`(`id`, `show_time`, `name`, `code`, `create_time`) VALUES (5, '2021-12-02 19:25:15', '赣州', '赣州-2-1', '2021-12-06 19:24:50');
INSERT INTO `show_data`(`id`, `show_time`, `name`, `code`, `create_time`) VALUES (6, '2021-12-03 19:25:18', '赣州', '赣州-3-1', '2021-12-06 19:24:52');
INSERT INTO `show_data`(`id`, `show_time`, `name`, `code`, `create_time`) VALUES (7, '2021-12-01 19:25:21', '九江', '九江-1-1', '2021-12-06 19:24:55');
INSERT INTO `show_data`(`id`, `show_time`, `name`, `code`, `create_time`) VALUES (8, '2021-12-02 19:25:24', '九江', '九江-2-1', '2021-12-06 19:24:58');
INSERT INTO `show_data`(`id`, `show_time`, `name`, `code`, `create_time`) VALUES (9, '2021-12-01 19:47:05', '南昌', '南昌-1-2', '2021-12-06 19:47:25');
INSERT INTO `show_data`(`id`, `show_time`, `name`, `code`, `create_time`) VALUES (10, '2021-12-01 19:47:18', '赣州', '赣州-1-2', '2021-12-06 19:47:27');

image.png

能注意到最下面两条数据的show_time是比第1条和第4条要新的,都是47分钟的数据,code也用了 -2 来区分

功能SQL

SQL中筛选了12月1日、12月2日、12月3日的数据记录,嵌套了两层分组函数,内层根据name、show_time分组去除重复数据,然后倒序,外层再根据去重并倒序的数据,作每日时间的分组,查询时自动取出了每组中的第一条,也就是每个城市每日最新的一条记录。

SELECT
	* 
FROM
	(
	SELECT
		* 
	FROM
		`show_data` 
	WHERE
		DATE_FORMAT( show_time, '%Y%m%d' ) IN ( '20211201', '20211202', '20211203' ) 
	GROUP BY
		`NAME`,
		show_time 
	ORDER BY
		show_time DESC 
	) x 
GROUP BY
	`NAME`,
	DATE_FORMAT( show_time, '%Y%m%d' )

最终结果

image.png

结束语

学艺不精,有小伙伴有优化的建议和方向吗?