mysql group by之后取每个分组最新的一条

mysql group by之后取每个分组最新的一条

参考文档:https://blog.csdn.net/u014508939/article/details/100561133

最近遇到一个需求就是需要从mysql中根据id查出一组数据,该组数据有36个类型,每种类型每天都会插入一条新的数据,然后我要拿每个类型的最新一条出来。

-- 首先我想的是,先按照类型分组,然后在按照时间去排序。
SELECT * FROM table r WHERE r.PAY_TABLE_ID='' GROUP BY r.PERIODS_NUMBER ORDER BY r.INSERT_DATE
-- 这样得出来的结果是最早更新进去的数据,并不是我要的最新的数据,这是为什么呢?我明明做了排序。
-- 上网查资料发现,是在分组之前数据库就默认得到了结果,然后我们在order by的时候就不会得到我们想要的结果。

第一种方法:根据上面的分析,我们要想得到想要的结果。

首先,使用GROUP_CONCAT函数 他可以设置分组的条件 在这里我们需要的条件就是时间最新的一条,语法如下:

-- 功能:将group by产生的同一个分组中的值连接起来,返回一个字符串结果。
-- 语法:group_concat( [distinct] 要连接的字段 [order by 排序字段 asc/desc  ] [separator '分隔符'] )
-- 说明:通过使用distinct可以排除重复值;如果希望对结果中的值进行排序,可以使用order by子句;separator是一个字符串值,缺省为一个逗号。

eg: SELECT GROUP_CONCAT(r.id ORDER BY r.INSERT_DATE DESC) FROM TABLE r WHERE r.PAY_TABLE_ID='' GROUP BY r.PERIODS_NUMBER ORDER BY r.INSERT_DATE

里面的id是我只查询id,然后条件就是插入时间倒叙,得到的结果就是把分组后的id都查询出来,但是我们只需要第一条,所以我们需要用到另外一个函数,没错!
第2步:SUBSTRING_INDEX截取函数 具体语法如下:

substring_index(str,delim,count)
     str:要处理的字符串
     delim:分隔符
     count:计数
例如:str=www.wikibt.com
      substring_index(str,'.',1)
      结果是:www
     substring_index(str,'.',2)
      结果是:www.wikibt
      也就是说,如果count是正数,那么就是从左往右数,第N个分隔符的左边的全部内容。相反,如果是负数,那么就是从右边开始数,第N个分隔符右边的所有内容,如:
      substring_index(str,'.',-2)
      结果为:wikibt.com

本处:SELECT SUBSTRING_INDEX(GROUP_CONCAT(r.id ORDER BY r.INSERT_DATE DESC),',',1) FROM SQRZ_PAY_TABLE r WHERE r.PAY_TABLE_ID='' GROUP BY r.PERIODS_NUMBER ORDER BY r.INSERT_DATE

这样 我们就得到了根据时间倒叙,分组后最新的数据了,但是只有id显然不是我们想要的,所以,最后一步就是经常用的 in 查询 把数据全部查询出来

SELECT * from table w where w.id in (SELECT SUBSTRING_INDEX(GROUP_CONCAT(r.id ORDER BY r.INSERT_DATE DESC),',',1) FROM table r WHERE r.PAY_TABLE_ID='' GROUP BY r.PERIODS_NUMBER ORDER BY r.INSERT_DATE)

以上是网上查询所得的一种方法。

第二种方法:使用mysql DATEDIFF(date1,date2)

定义和用法:DATEDIFF() 函数返回两个日期之间的天数。

eg:SELECT * FROM table r WHERE r.id='' AND DATEDIFF(r.INSERT_DATE,DATE(NOW()))=0

两个时间相差为0,也就是当天,故此也能得到想要的最新的数据。

第三种方法,如果存入数据库的时间是"yyyy-MM-dd"格式的时间,可以使用str-to-date

mysql日期和字符相互转换方法 
date_format(date,’%Y-%m-%d’) ————–>oracle中的to_char(); 
str_to_date('2020-01-19',’%Y-%m-%d’) ————–>oracle中的to_date();

%Y:代表4位的年份 
%y:代表2为的年份

%m:代表月, 格式为(01……12) 
%c:代表月, 格式为(1……12)

%d:代表月份中的天数,格式为(00……31) 
%e:代表月份中的天数, 格式为(0……31)

%H:代表小时,格式为(00……23) 
%k:代表 小时,格式为(0……23) 
%h: 代表小时,格式为(01……12) 
%I: 代表小时,格式为(01……12) 
%l :代表小时,格式为(1……12)

%i: 代表分钟, 格式为(00……59) 【只有这一个代表分钟,大写的I 不代表分钟代表小时】

%r:代表 时间,格式为12 小时(hh:mm:ss [AP]M) 
%T:代表 时间,格式为24 小时(hh:mm:ss)

%S:代表 秒,格式为(00……59) 
%s:代表 秒,格式为(00……59)

eg:SELECT * FROM table r WHERE r.id='' AND r.INSERT_DATE=str-to-date('2020-02-14','%Y-%m-%d')
# mysql 

评论

Your browser is out-of-date!

Update your browser to view this website correctly. Update my browser now

×