mysql - 如何在 MySql 中打乱一列

标签 mysql shuffle

在找不到符合我需要的任何内容后,我编写了这段代码以始终如一地随机排列 mysql 中列的值。有更好的方法吗?

**Original table:**
+----+-----------+
| id | fname     |
+----+-----------+
|  1 | mike      |
|  2 | ricky     |
|  3 | jane      |
|  4 | august    |
|  6 | dave      |
|  9 | Jérôme    |
+----+-----------+

**Possible output:**
+----+-----------+
| id | fname     |
+----+-----------+
|  1 | dave      |
|  2 | jane      |
|  3 | mike      |
|  4 | ricky     |
|  6 | Jérôme    |
|  9 | august    |
+----+-----------+

DROP TEMPORARY TABLE IF EXISTS shuffle1;
DROP TEMPORARY TABLE IF EXISTS shuffle2;
CREATE TEMPORARY TABLE shuffle1 (id int(11) NOT NULL AUTO_INCREMENT, PRIMARY KEY (id), original_values varchar(255), key original_values(original_values) );
CREATE TEMPORARY TABLE shuffle2 (id int(11) NOT NULL AUTO_INCREMENT, PRIMARY KEY (id), original_ids int(11), key original_ids(original_ids) );
INSERT INTO shuffle1 (id, original_values) SELECT NULL, table1.fname FROM table1 ORDER BY rand();
INSERT INTO shuffle2 (id, original_ids) SELECT NULL, table1.id FROM table1;
UPDATE table1 SET table1.fname = (SELECT shuffle1.original_values FROM shuffle1 JOIN shuffle2 ON shuffle2.id = shuffle1.id WHERE table1.id = shuffle2.original_ids);

最佳答案

如果您不介意某些表数据无法处理(取决于表大小,预计 50% 的行无法处理),这里有一个解决方案:

原始表格

id  name
1   Some
2   Body
3   Once
4   Told
5   Me
6   The
7   World
8   Is
9   Gonna
10  Roll
11  Me
12  I 
13  Ain't
14  The 
15  Shapest
16  Tool
17  In
18  The
19  Shed
20  She
21  was
22  looking
23  kind
24  of
25  dumb
26  with
27  her
28  finger
29  and
30  her
31  thumb

查询:

SELECT new_id, name FROM (
    SELECT  new_id, name FROM (
        SELECT new_meme.id as new_id, original_meme.id as original_id, original_meme.name FROM meme original_meme
        JOIN meme new_meme ON new_meme.id <>  original_meme.id
        ORDER BY RAND()
    ) layer1
    GROUP BY layer1.new_id
) layer2 GROUP BY name

结果(当然每次运行都不同)

1   I 
2   In
3   Gonna
4   Ain't
5   The
6   her
7   finger
8   Some
9   dumb
10  She
15  Me
16  with
17  Told
18  and
19  World
21  Roll
22  The 
25  Tool
26  Shed
27  Is
28  Me
29  Sharpest
31  The

注意:您可能会发现查询非常慢,这是因为它连接了两次表,所以如果数据大小为1000,则需要处理1000 * 1000.

您可以通过更改 ON new_meme.id <> original_meme.id 来控制查询速度至 ON new_meme.id BETWEEN original_meme.id - 5 AND original_meme.id +5 (5 可以更改),但它会降低随机性并且不适用于非数字 id

关于mysql - 如何在 MySql 中打乱一列,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/18518594/

相关文章:

javascript - 尝试将选项添加到MySQL表的数据列表中,但选项并不总是显示(Node.js)

php - Facebook-wall like MySQL结构问题

c++ - 如何在 C++ 中打乱对象 vector

c - 用指针在c中打乱链表

php - 无法从 php 将 ids 添加到 mysql 中的字段

php - 从其他类访问登录的 User 对象的最佳实践

php - 在 HTML 网页中显示 SQL 查询结果

algorithm - 惰性洗牌算法

javascript - 使用 javascript 随机整数填充顺序 html 区域

javascript - 最高效的阵列洗牌器