我将其放在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(红色,蓝色,岩石,帽子)

这有效:

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,后者引用在并集的第一半部中选择的单词。

最佳答案

如您所见,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


这将在外部查询(而不是子查询)中进行排序,并实现所需的排序类型。

关于mysql - 带ORDER BY RAND()的UNION仅与LIMIT在MySQL上一起使用,我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/45684883/

10-16 20:56