mysql5.7先group by分组再order by取最新一条记录时失效

方案一:利用distinct关键字,这里distinct其实起到了一个固定排序的作用

SELECT
	*
FROM
	(
		SELECT DISTINCT
			t1.*, 
			t2.type,
			t2.price
		FROM
			t1
		LEFT JOIN t2 ON t1.type_id = t2.id
		ORDER BY
			t1.end_time DESC
	) t
GROUP BY
	t.type

方案二:利用limit关键字,这里limit其实也是起到了一个固定排序的作用,这种因为要尽可能的使limit的数量比较大,所以不是很推荐,如果是对一些已知且数据量小的表的话也是可以用的

SELECT
	*
FROM
	(
		SELECT
			t1.*,
			t2.type,
			t2.price
		FROM
			t1
		LEFT JOIN t2 ON t1.type_id = t2.id
		ORDER BY
			t1.end_time DESC
		LIMIT 99999(超过表记录数或者可预知的最大记录数)
	) t
GROUP BY
	t.type

方案三:先对一个唯一列分组排序,一般是主键,最后再对查询的记录进行实际字段的分组,其实原理还是固定排序,防止最后分组的时候破坏原有的排序

SELECT
	*
FROM
	(
		SELECT
			t1.*, 
			t2.type,
			t2.price
		FROM
			t1
		LEFT JOIN t2 ON t1.type_id = t2.id
		GROUP BY
			t1.id
		ORDER BY
			t1.end_time DESC
	) t
GROUP BY
	t.type

方案四:利用SUBSTRING_INDEX函数截取主键然后再分组,跟方案三其实思路一样,实现方式不同

SELECT
	t1.*, 
	t2.type,
	t2.price
FROM
	t1
LEFT JOIN t2 ON t1.type_id = t2.id
WHERE
	t1.id IN (
		SELECT
			SUBSTRING_INDEX(GROUP_CONCAT(t.id ORDER BY t.end_time DESC), ',', 1)
		FROM
			(
				SELECT
					t3.*, 
					t4.type,
					t4.price
				FROM
					t3
				LEFT JOIN t4 ON t3.type_id = t4.id
				ORDER BY
					t3.end_time DESC
			) t
		GROUP BY
			t.type
	)

方案五:sql不分组,在代码利用循环中比较结束时间,取出每种分组最后一条记录放入新集合中,这种是最容易理解的方案,但是代码略显臃肿

方案六:sql不分组,在代码中利用stream的sorted排序然后groupingBy分组,这样的结果是分组的字段为key,分组的数据为list的一个map,在声明返回结果类型和中间类型类型时注意要返回一个有序的map,TreeMap或者LinkedHashMap,这样你根据key取每一组的第一条数据就是你最开始sorted排序的第一条,下边简单写一个例子:

List<StudentVO> studentVOList = new ArrayList<>();
LinkedHashMap<String, List<StudentVO>> studentVOListMap = studentVOList.stream()
        .sorted(Comparator.comparing(StudentVO::getEndTime).reversed())
        .collect(Collectors.groupingBy(s -> s.getType(), LinkedHashMap::new,        Collectors.toList()));
        
studentVOListMap.forEach((type, list) -> {
        StudentVO studentVO = list.get(0);
});

方案七:sql不分组,在代码中利用stream的groupingBy分组,然后再对返回的map中的value进行排序,这个对返回的map类型没有具体要求,其实思路都差不多,看个人习惯和偏好吧,下边也是一个简单的例子:

List<StudentVO> studentVOList = new ArrayList<>();
HashMap<String, StudentVO> map = list.stream()
        .collect(Collectors.groupingBy(StudentVO::getType, HashMap::new, 
                        Collectors.collectingAndThen(Collectors.toList(), list -> list.stream()
                        .sorted(Comparator.comparing(StudentVO::getEndTime).reversed())
                        .findFirst().get())));
        
map.forEach((key, value) -> {
        StudentVO studentVO = value;
});

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值