mysql探索(一) 关于排重+排序的处理

问题

如何把数据按照某一个字段排重保留我们要的哪行记录,然后以我们想要的顺序排序好以后,查询出来?

今天花了一整天的时间搞这个问题,本来以为是很简单的问题就小瞧它了,结果发现网上一大堆错误答案,我也是醉了。。

 文章略长,主要讲述的是我的探索(踩坑)过程,想要直接看解决方法的请拉到最后,拿走不谢~

过程

先说一下问题所在,比如说,现在有一个表,体温测量。结构如下:

 

 假设我们每隔一段时间去给用户测量一次体温,那么同一个用户就会产生多条记录。现在我们想要查询出每一个用户最新一条测量数据,怎么查?

接下来我说说我的踩坑历程:

是不是觉得很简单,先分组,把重复的数据排掉:

select * from tplay_temperature_record group by user_id;

查询结果:

 

 我去,不对啊,我想要的是最新的一条,id为51的那条数据才是我想要的啊,怎么给我返回了id为50的?不行,看来我得先排好序,再进行排重,(这个时候我以为group by拿的是第一条):

 第一步,先排序:

select * from tplay_temperature_record order by create_time desc;

看到结果,已经排好序了。

 

 然后我们用到子查询去进行分组:

select * from (select * from tplay_temperature_record order by create_time) as a group by a.user_id;

结果:

 

 我去,不对啊,id为51的那条,咋又给我整没了。

然后我开始在网上各种搜,在这个地址:https://blog.csdn.net/weixin_38450840/article/details/88836170

发现有人这样说:

 

 

 

 

 卧槽,这样子的吗?原谅我年少无知,才疏学浅,那么我们试试,加上limit:

select * from (select * from tplay_temperature_record order by create_time limit 100) as a group by a.user_id;

结果:

 

 

 还是一样,没有任何改变,我不知道是不是mysql版本太低的原因,我用的是5.5.62,反正就是没效果。

 

再看看其他大神的思路吧

于是我找到了这篇文章:https://blog.csdn.net/u012660464/article/details/78605078/

这篇文章的核心思想是:先分组,再排序。

对啊,我们想的是先排序再分组,如果反过来呢?

文章里说到:

 

 

 

按照他说的,写一个:

SELECT *  FROM  (select * from tplay_temperature_record  order by user_id, create_time DESC) b 
GROUP BY b.user_id;

结果:

 

 

 啥情况,还是不对?接着往下翻,看到底下评论一堆叫苦连天的。。

 

 

 

 

 好吧,看来广大网友和我一样,没从这篇文章中获得什么~

 

解决

喜闻乐见的环节来了,在无数次的挣扎之后,终于获得了正确的方法,也是参考了下面这篇文章,感谢大神!

地址:https://www.cnblogs.com/afei-happy/p/3783520.html

核心思想,两个表的思想,就是先分组作为另一个表,然后进行子查询,用user_id去关联,对结果进行排序。

上步骤:

第一步,分组,排除重复,保留想要的哪一行记录。这里我们是按照user_id排重,查询时间最近的那条,就可以这样写:

 

SELECT
            user_id,
            max(create_time) max_day,
            temperature
        FROM
            tplay_temperature_record
        GROUP BY
            user_id

第二步,子查询,把上述的查询结果当成另一个表B,然后原表当成表A,用user_id去关联,然后对查询到的结果进行排序。

SELECT
    A.*
FROM
    tplay_temperature_record A,
    (
        SELECT
            user_id,
            max(create_time) max_day,
            temperature
        FROM
            tplay_temperature_record
        GROUP BY
            user_id
    ) B
WHERE
    A.user_id = B.user_id
AND A.create_time = B.max_day
ORDER BY
    A.create_time DESC

结果:

 

 

 

完美!

总结一下,这一类问题,看似简单,其实复杂。

我自己感觉这个问题有两个难点:

1、group by分组后如何保留自己想要的那一行数据?搭配聚合方法,或许有奇效

2、分组后的数据如何排序?其实不太好排序,为何不变通一下,分成两个表,然后关联一下查询再排序呢?

除了这种方法,肯定有其他的,如果有其他方法的,希望在评论区大家一起讨论下。

 

---------------------------------------------------------------------------------------------------------------------------------------

不好意思,找到一个更简单的写法:

SELECT
    *,
    max(create_time) max_day
FROM
    tplay_temperature_record
GROUP BY
    user_id
ORDER BY
    max_day DESC

 都不需要用到“两个表”的思想。

注:这种写法仅适用于只需要这两个字段的写法。并不能真正想要的哪一行的所有字段,如果想要得到,需要再查询一次,或者使用上面的那种方法。

posted on 2020-08-31 16:55  little天  阅读(969)  评论(0编辑  收藏  举报

导航