多个版本数据只取最新版本"/>
MySQL查询多个版本数据只取最新版本
前言
最近接到新的客户需求,在查询指标时要求相同的指标只显示一条数据,要显示的那条数据的要求如下:
1. 如果同一个指标的不同版本中有一条是处于上线状态,则显示该条数据,不管版本号是多少
2. 如果该条指标没有处于上线状态的版本,则展示最高版本的数据
3. 如果该条指标的相同版本有多条数据,则显示最新创建的那一条
由于对group by不熟悉,弄了好久才弄好。以下是可用的SQL语句:
-- 字段解释:
-- TARGET_GRP_NAME:指标名称;
-- TARGET_GRP_ID:指标组ID,相同的指标拥有共同的指标组ID;
-- ID_:指标ID,指标数据的序列号,唯一
-- TARGET_STATUS:指标状态,其中3表示上线状态
-- version:指标版本号
-- CREATE_TIME:指标的创建时间
select * from (select ID_, TARGET_GRP_NAME, version, TARGET_GRP_ID, TARGET_STATUS, CREATE_TIME, case when TARGET_STATUS='3' then 1 else 0 end as sort from 指标信息表group by TARGET_GRP_ID, sort, version, CREATE_TIME order by TARGET_GRP_ID, sort desc ,VERSION desc, CREATE_TIME desc
) b
group by b.TARGET_GRP_ID;
探索过程
光有一条SQL,可能并不明白是什么意思,所以在这里记一下自己的摸索过程,也算是详细说明一下实现的思路。
第一步 使用group by
需求乍一看,就是要根据指标组ID进行分组而已,于是产生了第一条SQL:
select ID_, TARGET_GRP_NAME, version, TARGET_GRP_ID, TARGET_STATUS, CREATE_TIME
from 指标信息表
group by target_grp_id
然后我发现,结果集中每一个指标组只显示了一条数据,而且不是我想要的那条,于是我查询了group by到底返回的是哪一条数据,得到如下结论:
group by 会返回分组内默认的第一条数据
于是我就想看看所有数据到底是怎么排序的,于是产生了第二条SQL:
select ID_, TARGET_GRP_NAME, version, TARGET_GRP_ID, TARGET_STATUS, CREATE_TIME
from 指标信息表
group by target_grp_id, TARGET_STATUS,version, create_time
因为我的数据只需要根据这几个字段分组,所以我只group by了这几个字段,于是我就得到了所有的数据:
ID_ | TARGET_GRP_NAME | version | TARGET_GRP_ID | TARGET_STATUS | CREATE_TIME |
---|---|---|---|---|---|
fe9d8f5a3a7d4dc894a743c66591e917 | COPY_1101 | 1.0 | app_index_100000000226_m | 1 | 2019-11-01 09:49:30 |
03fc316f0b16423c9a73ddef70a438d3 | 基础指标-hzy-1106-1 | 1.0 | app_index_100000000230_d | 1 | 2019-11-13 11:31:59 |
2bf10789f6694c4abfc73f8278c11dbe | 基础指标-hzy-1106-1 | 1.0 | app_index_100000000230_d | 3 | 2019-11-06 16:30:01 |
7c2c4b054f064e16b71e42840d8e1423 | 基础指标-hzy-1106-1 | 0.0 | app_index_100000000230_d | 7 | 2019-11-06 16:30:01 |
8e05421dd05641abbd60323702af802a | 计算指标-hzy-1106 | 0.0 | app_index_100000000231_d | 1 | 2019-11-06 16:40:21 |
93d07d9cee3042d6b8d5b67b9aa5dc61 | HYS_COPY_1016_006_F | 1.0 | app_index_100000000233_d | 1 | 2019-10-16 11:56:17 |
c67fd89d9dd646849ca13b26a3007d72 | HYS_COPY_1016_006_B | 1.0 | app_index_100000000233_d | 1 | 2019-11-13 11:05:43 |
上面的结果中,有两条数据是需要好筛选的,其中我所需要的数据是这两条:
ID_ | TARGET_GRP_NAME | version | TARGET_GRP_ID | TARGET_STATUS | CREATE_TIME |
---|---|---|---|---|---|
2bf10789f6694c4abfc73f8278c11dbe | 基础指标-hzy-1106-1 | 1.0 | app_index_100000000230_d | 3 | 2019-11-06 16:30:01 |
c67fd89d9dd646849ca13b26a3007d72 | HYS_COPY_1016_006_B | 1.0 | app_index_100000000233_d | 1 | 2019-11-13 11:05:43 |
但是他们在各自的分组内并不是第一条,也就是说,group by并不会默认返回他们。于是我就想,我把他们进行排序,放到第一个不就得了?因为我的需求中状态是最优先的,他会无视版本高低的问题,所以我也引入了新的字段对他进行排序:
select ID_, TARGET_GRP_NAME, version, TARGET_GRP_ID, TARGET_STATUS, CREATE_TIME, case when target_status='3' then 1 else 0 end as sort
from 指标信息表
group by target_grp_id,TARGET_STATUS,version, create_time
order by target_grp_id, sort desc
然后我发现,基础指标-hzy-1106-1 这条数据果然排到了组内第一个;
但是随之我发现,HYS_COPY_1016_006_B这条数据的排序还是不对,但这已经不是问题了,order by再加一个字段就行:
select ID_, TARGET_GRP_NAME, version, TARGET_GRP_ID, TARGET_STATUS, CREATE_TIME, case when target_status='3' then 1 else 0 end as sort
from 指标信息表
group by target_grp_id, TARGET_STATUS,version, create_time
order by target_grp_id, sort desc, CREATE_TIME desc
于是我发现,数据的排序终于符合我的要求了,然后就有了最终的SQL:
select * from (select ID_, TARGET_GRP_NAME, version, TARGET_GRP_ID, TARGET_STATUS, CREATE_TIME, case when TARGET_STATUS='3' then 1 else 0 end as sort from 指标信息表group by TARGET_GRP_ID, sort, version, CREATE_TIME order by TARGET_GRP_ID, sort desc ,VERSION desc, CREATE_TIME desc
) b
group by b.TARGET_GRP_ID;
更多推荐
MySQL查询多个版本数据只取最新版本
发布评论