场景
需求场景:有一批包含城市名称和城市的不同时间段的数据,需要筛选出在不同城市,每天时间最晚的那条记录,需要对城市名称、时间进行分组并倒序,筛选出时间最晚的那条
思路
考虑用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');
能注意到最下面两条数据的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' )
最终结果
结束语
学艺不精,有小伙伴有优化的建议和方向吗?