如何在MySQL中进行动态UNION查询?

时间:2014-10-29 15:08:18

标签: mysql sql

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类型变量?
  • 我希望最重要的是我正在思考这个问题,并且有一种方法可以在SELECT语句中执行此操作。

1 个答案:

答案 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