有这样一种需求,需要查询同一张表里面不同类型的前n条数据。
这边提供了几种写法:
假设要查询每种分类点击量前三的数据,type为类型字段,clickNum为点击数。
第一种:
select
from
table AS a
where
(select COUNT() from table AS b where b.type= a.type AND b.clickNum >= a.clickNum) <= 3
ORDER BY a.type_id asc,a.clickNum DESC;
用上面的方法,有一个问题,就是如果记录的点击数刚好有一摸一样的,就容易漏掉数据。而且如果数据量一大,上面的查询性能是非常差的。基本是数据条数的平方这样的量级。比如如果有100条数据,那可能就是要查询10000次。
是国外某个人写的一种方法,测试过,可以用。
set @num := 0, @type := '';
SELECT FROM
(SELECT ,
@num := if(@type = type, @num + 1, 1) as row_num,
@type := type
FROM table
order by type ASC,clickNum DESC)
as temp
WHERE temp.row_num <=3;
第三种
我最后采用的方式,就是用union all。写法如下:
(select from table where type = ‘apple’ order by price limit 2)
union all
(select from table where type = ‘orange’ order by price limit 2)
union all
(select from table where type = ‘pear’ order by price limit 2)
union all
(select from table where type = ‘cherry’ order by price limit 2)
说白了对每种类型根据你所要条件进行查询,然后用union all进行连接即可。当然我之所以采用这种方式是因为在mybatis里面也可以实现该写法,如下
<select id=“selectdatabyType” resultMap=“ResultMapWithBLOBs” >
<foreach collection=“list” item=“item” index=“index” separator=“union all”>
(select
<include refid=“Base_Column_List” />
from
table where type = ${item.id} and status=1 order by clickNum DESC limit 0,3)
</foreach>
</select>
上面的实现的关键是,记得加()。