mytable
有一个自动递增的id
列是一个整数,对于所有意图和目的在这种情况下你可以放心地假设更高的ID代表一个更近期的价值。 mytable
还有一个名为group_id
的索引列,它是groups
表的外键。
我想要一个快速而肮脏的查询,从group_id
为每个mytable
选择最近的5行。
如果只有三个小组,这很容易,因为我可以这样做:
SELECT * FROM `mytable` WHERE `group_id` = 1 ORDER BY `id` DESC LIMIT 5
UNION ALL
SELECT * FROM `mytable` WHERE `group_id` = 2 ORDER BY `id` DESC LIMIT 5
UNION ALL
SELECT * FROM `mytable` WHERE `group_id` = 3 ORDER BY `id` DESC LIMIT 5
然而,没有固定数量的组。组由groups
表中的内容确定,因此它们的数量不确定。
到目前为止我的想法:
CURSOR
表上获取groups
并构建一个新的SQL查询字符串,然后EXECUTE
。然而,这似乎非常混乱,我希望有更好的方法。CURSOR
表上抓取groups
并将内容插入临时表中,然后从中进行选择。然而,这似乎也很麻烦。CURSOR
,然后直接从那里返回行。是否有类似于SQL Server的@table
类型变量?答案 0 :(得分:1)
要获得n个最新的每组行最好由其他RDBMS(SQL Server,Postgre Sql,Oracle等)中的窗口函数处理,但遗憾的是MySql没有任何窗口函数,所以替代方案有一个解决方案在这种情况下,使用用户定义的变量为属于同一组的行分配排名ORDER BY group_id,id desc
对于按组正确排序结果非常重要
SELECT c.*
FROM (
SELECT *,
@r:= CASE WHEN @g = group_id THEN @r + 1 ELSE 1 END rownum,
@g:=group_id
FROM mytable
CROSS JOIN(SELECT @g:=NULL ,@r:=0) t
ORDER BY group_id,id desc
) c
WHERE c.rownum <=5
上面的查询会为每个group_id
提供5个最近的行,如果您想获得超过5行,只需将外部查询的过滤器更改为所需的数字WHERE c.rownum <= n