具有ORDER BY RAND()的UNION仅适用于MySQL上的LIMIT

时间:2017-08-15 00:23:36

标签: mysql

我把它放在SQLFiddle上并按预期工作,但在大学MySQL引擎上,它的工作方式不同:http://sqlfiddle.com/#!9/9d975f/3

我有一个包含单词及其类别的列表:

id, word, category
1, red, color
2, blue, color
3, brick, item
4, rock, item
5, hat, item
6, glove, item
7, cape, item
8, cup, item
9, love, feeling
... etc

我需要8个单词,其中前4个是颜色和项目的混合,但最后4个只是项目,单词必须随机选择并且是唯一的。

例如:蓝色,帽子,岩石,红色,砖,手套,杯子,斗篷(颜色,项目,项目,颜色,项目,项目,项目,项目)

我无法在单个查询中执行此操作,因此我首先运行查询以获取上半部分的ID列表,例如,1,2,4,5(红色,蓝色,摇滚,帽子)< / p>

这有效:

SELECT * FROM word WHERE id IN (1, 2, 4, 5) ORDER BY RAND() 

总是以随机顺序给我单词1,2,4和5。但是当在UNION中用作子查询时:

SELECT * FROM (SELECT * FROM word WHERE id IN (1, 2, 4, 5) ORDER BY RAND() ) a 
UNION 
SELECT * FROM (SELECT * FROM word WHERE id NOT IN (1, 2, 4, 5) AND category='item' ORDER BY RAND() LIMIT 4) b

前4个单词总是按顺序排列,例如:给我1,2,4,5,8,3,7,6。但是,如果我指定限制:

SELECT * FROM (SELECT * FROM word WHERE id IN (1, 2, 4, 5) ORDER BY RAND() LIMIT 4) a 
UNION 
SELECT * FROM (SELECT * FROM word WHERE id NOT IN (1, 2, 4, 5) AND category='item' ORDER BY RAND() LIMIT 4) b

它按预期正常工作。我以随机顺序得到红色,蓝色,岩石和帽子,然后是随机顺序的4个项目,不包括摇滚和帽子。

我理解UNION有一个删除重复项的规则列表,但我很困惑为什么包含限制会改变行为。

理想情况下,我想在单个查询中完成此操作,但我无法弄清楚如何在联合的下半部分执行NOT IN,该联合引用在联合的前半部分中选择的单词。

2 个答案:

答案 0 :(得分:0)

正如您所注意到的,UNION具有重复数据删除功能。此函数通常与哈希合并一起使用。它使有助于合并的子查询中的任何ORDER BY子句的效果无效。 (有些DBMS说“你不能在绑定到ORDER BY的子查询中使用UNION”,但是MySQL允许你这样做。)

您可以尝试这样的方法来解决问题。

SELECT word
   FROM (
       SELECT word, RAND() random FROM word WHERE  id IN (1, 2, 4, 5) 
       UNION
       SELECT word, 1.0+RAND() random FROM word WHERE id NOT  (1, 2, 4, 5) 
   ) w
  ORDER BY random

这将在外部查询中进行排序,而不是子查询,并且将实现您想要的那种排序。

答案 1 :(得分:0)

尝试使用UNION ALL代替UNION。这会禁用UNION的重复抑制功能,并且可能会保留来自子查询的顺序。

相关问题