【问题标题】:Randomize order of two columns per row in a query随机化查询中每行两列的顺序
【发布时间】:2018-07-24 18:42:24
【问题描述】:

我想将行从一个 MySQL 表复制到另一个,同时随机化两个字段的顺序,即我想从 table1 中取出带有字段 id,a,b 的行并将它们插入table2,但在随机行上交换 ab

这是我尝试过的:

INSERT INTO table2 (id, a, b)
  SELECT
    id,
    IF(@r=RAND() < 0.5, a, b),
    IF(@r        < 0.5, b, a)
  FROM table1
  WHERE table1.filter = 42;

我预计这会为每行生成一个随机数,但实际上它只为每个查询生成一个随机数,所以它要么是所有行的 a,b,要么是所有行的 b,a。我需要改变什么?


P.S:我使用变量是因为在两个 IF 中调用 rand() 会生成两个单独的数字,并且我可以两次获得相同的字段。没有变量有没有办法做到这一点?

【问题讨论】:

  • a 和 b 的数据类型是什么?
  • SMALLINT UNSIGNED
  • 如果您将= 更改为:= 并将分配移到外面(即SELECT @r := RAND() &lt; 0.5, IF(@r &lt; 0.5, a, b), ...),它会起作用,但我不知道它为什么会这样。 RAND() 按行计算。
  • 让选择写出@r,你会看到问题:-)(提示-添加括号-(@r:=RAND()) &lt; 0.5)。
  • 哦,是的……Salman 对:= 的看法当然是对的,但一旦我纠正了这一点,结果让我更加困惑。正如 Roman 所暗示的,@r=rand()&lt;0.5 需要在赋值周围加上括号,否则结果将被反转

标签: mysql sql random


【解决方案1】:

使用@variables 似乎可行,但 MySQL discourages assigning and reading values to variables inside same statement 因为:

... 涉及用户变量的表达式的求值顺序 未定义。

更好的解决方案如下:

-- INSERT INTO ...
SELECT
  id,
  IF(r < 0.5, a, b),
  IF(r < 0.5, b, a)
FROM (
  SELECT id, a, b, RAND() AS r
  FROM table1
  WHERE table1.filter = 42
) x

【讨论】:

    【解决方案2】:
    INSERT INTO table2 (id, a, b)
    set @r=0;
      SELECT
        id,
        IF(@r=RAND() < 0.5, a, b),
        IF(@r        < 0.5, b, a)
      FROM table1
      WHERE table1.filter = 42;
    

    【讨论】:

    • 感谢您提供此代码 sn-p,它可能会提供一些有限的短期帮助。一个正确的解释would greatly improve 它的长期价值通过展示为什么这是一个很好的解决问题的方法,并将使它对未来有其他类似问题的读者更有用。请edit您的回答添加一些解释,包括您所做的假设。
    猜你喜欢
    • 2017-08-26
    • 1970-01-01
    • 2012-02-17
    • 2011-09-05
    • 2020-12-10
    • 2017-04-09
    • 1970-01-01
    • 2019-02-01
    • 1970-01-01
    相关资源
    最近更新 更多