mytable
有一个自动递增的 id
列,它是一个整数,并且出于所有意图和目的在这种情况下您可以安全地假设较高的 ID 表示较新的值。 mytable
还有一个名为 group_id
的索引列,它是 groups
表的外键。
我想要一个快速而肮脏的查询来为 mytable
中的每个 group_id
选择最近的 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
表中的内容决定,因此组的数量不确定。
到目前为止我的想法:
- 我可以在
groups
表上获取一个CURSOR
并构建一个新的 SQL 查询字符串,然后EXECUTE
它。但是,这看起来真的很麻烦,我希望有更好的方法。 - 我可以在
groups
表上获取一个CURSOR
并将内容插入临时表,然后从中进行选择。然而,这看起来也很乱。 - 我不知道我是否可以只获取一个
CURSOR
然后直接从那里开始返回行。是否有类似于 SQL Server 的@table
类型变量的东西? - 我最希望的是我想多了,有一种方法可以在 SELECT 语句中做到这一点。
最佳答案
要获得每组最近的 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 过滤器更改为你想要的数字 WHERE c.rownum <= n
关于mysql - 如何在 MySQL 中执行动态 UNION 查询?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/26633907/