我有一个使用union来连接两个子查询的查询,例如
SELECT * FROM posts WHERE postTypeId=1 (e.g. blog)
UNION
SELECT * FROM posts WHERE postTypeId=2 (e.g. news)
此方法生成的结果集按顺序排列两个子集(“blog”,然后是“news”)。
我想创建一个结果集,它将两者交错,在“blog”子集和“news”子集的行之间交替。
我觉得必须有一个简单的方法来做到这一点,但我找不到它。
任何建议都将不胜感激。
尼克
答案 0 :(得分:3)
这是最适合我的解决方案。它与当前的任何提案都不相同,所以我已经单独添加了它。 @ a,@ b和@c用于为每个子集创建行号,这意味着在组合结果中,3行将共享相同的行号(“行集”)。这用作第一顺序排序,然后二阶排序对“行集”中的行进行排序。
SET @a = 0;
SET @b = 0;
SET @c = 0;
SELECT * FROM(
SELECT @a := @a + 1 AS sortOne, 1 AS sortTwo, posts.* FROM posts WHERE posts.postTypeId=3
UNION
SELECT @b := @b + 1 AS sortOne, 2 AS sortTwo, posts.* FROM posts WHERE posts.postTypeId=2
UNION
SELECT @c := @c + 1 AS sortOne, 3 AS sortTwo, posts.* FROM posts WHERE posts.postTypeId=1
) AS result ORDER BY sortOne, sortTwo
这个解决方案是由提交的解决方案衍生/启发的,但我认为将它们中的任何一个标记为本身已被接受的解决方案并不合适。所以,归功于托马斯克莱森,托尼霍普金森和鲁蒙兹的答案,我已经投票了。干杯!
答案 1 :(得分:1)
嗯,这是一种我能想到的新方式(未经测试,但你会得到主旨):
SELECT * FROM (
SELECT 1 AS query, @n := @n + 1 AS rowNumber, posts.* FROM (select @n:=0), posts WHERE posts.postTypeId=1
UNION
SELECT 2 AS query, @n := @n + 1 AS rowNumber, posts.* FROM (select @n:=0), posts WHERE posts.postTypeId=2
) ORDER BY rowNumber, query;
因此,这将执行两个查询,然后先按rowNumber
再按query
进行排序。你最终得到的是:
rowNumber | query
1 | 1
1 | 2
2 | 1
2 | 2
etc...
SELECT @n=:0
将全局变量n
重置为0,然后@n := @n + 1
增加每行的值。
如果您需要更多解释,请与我们联系。我希望这有效! :)
答案 2 :(得分:1)
尝试
Set @current_row = 0
Select * From (
SELECT @current_row := @current_row + 1 as Position, posts.* FROM posts WHERE postTypeId=1
UNION
SELECT @current_row, posts.* FROM posts WHERE postTypeId=2
) dummyTableName
order by position, postTypeId
也许
答案 3 :(得分:1)
这很简单,您可以在子查询中添加参数,参数“rank”,这样:
SET @rank=0;
SELECT @rank:=@rank+2 AS rank FROM posts WHERE postTypeId=1 (e.g. blog)
然后,你得到:
0, ...
2, ...
如果你在其他查询中做同样的事情但是初始化等级为1,你会得到:
1, ...
3, ...
最后“排名等级”,你会得到帖子和新闻混合。