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_NAMEversionTARGET_GRP_IDTARGET_STATUSCREATE_TIME
fe9d8f5a3a7d4dc894a743c66591e917COPY_11011.0app_index_100000000226_m12019-11-01 09:49:30
03fc316f0b16423c9a73ddef70a438d3基础指标-hzy-1106-11.0app_index_100000000230_d12019-11-13 11:31:59
2bf10789f6694c4abfc73f8278c11dbe基础指标-hzy-1106-11.0app_index_100000000230_d32019-11-06 16:30:01
7c2c4b054f064e16b71e42840d8e1423基础指标-hzy-1106-10.0app_index_100000000230_d72019-11-06 16:30:01
8e05421dd05641abbd60323702af802a计算指标-hzy-11060.0app_index_100000000231_d12019-11-06 16:40:21
93d07d9cee3042d6b8d5b67b9aa5dc61HYS_COPY_1016_006_F1.0app_index_100000000233_d12019-10-16 11:56:17
c67fd89d9dd646849ca13b26a3007d72HYS_COPY_1016_006_B1.0app_index_100000000233_d12019-11-13 11:05:43

上面的结果中,有两条数据是需要好筛选的,其中我所需要的数据是这两条:

ID_TARGET_GRP_NAMEversionTARGET_GRP_IDTARGET_STATUSCREATE_TIME
2bf10789f6694c4abfc73f8278c11dbe基础指标-hzy-1106-11.0app_index_100000000230_d32019-11-06 16:30:01
c67fd89d9dd646849ca13b26a3007d72HYS_COPY_1016_006_B1.0app_index_100000000233_d12019-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;
  • 1
    点赞
  • 6
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值