在开发过程中,经常会遇到需要对不同的分类情况下获取相应分类下制定排序的前N条数据。一种比较慢的办法是先查询总共有几个分类,然后根据分类id再去获取前N条数据,这样一共需要进行1+N次数据库查询。这里给出一种,可以只根据一条MySQL语句查询,然后把查询结果在JAVA代码中进行处理获取需要的结果。
举个栗子:
1、 创建表 tb_info
create table tb_info(
`id` bigint unsigned not null AUTO_INCREMENT,
`sort_id` int unsigned not null default 0 comment '分类id',
`sort_name` varchar(255) not null default '' comment '分类名称',
`value` varchar(255) not null default '' comment '信息字段',
`ctime` bigint unsigned not null default 0 comment '创建时间',
PRIMARY KEY (`id`)
) Engine = InnoDB default charset=UTF8 comment '信息表';
2、插入数据
insert into tb_info (`sort_id`, `sort_name`, `value`, `ctime`) values(1, "分类1", "111", 11), (1, "分类1", "123", 10),(1, "分类1", "2323", 12),(2, "分类2", "3333", 123),(2, "分类2", "3334", 45), (3, "分类3", "4456", 87);
3、查询每个分类根据ctime值逆序的前2个值
SELECT
*
FROM
tb_info AS a
JOIN (
SELECT
sort_id,
GROUP_CONCAT(id) AS ·id_set·
FROM
tb_info
GROUP BY
sort_id
) AS b ON a.sort_id = b.sort_id
AND FIND_IN_SET(a.id, b.`·id_set·`) BETWEEN 1
AND 2
ORDER BY
a.`ctime` DESC;
输出结果为:
这样我们就可以获取到一组所有分类下的所有信息的前2条。
4、Java代码处理
将获取取到的分类数乘以每个分类的个数的总的条数,进行java处理,然后分类获取数据给前端。
分析:
上述代码先将所有分类聚合到GROUP_CONCAT(),然后再通过FIND_IN_SET进行查找。注意:order by 是对整个表进行先排序,然后再通过FIND_IN_SET进行截取。