Mic*_*wan 5 mysql order-by auto-increment random
我有一个表,其中包含进入其他表的几个键(其中每个键由多列组成)。我想为每个键创建一个新列,该列将是一个整数,以便该值i
表示该ith
键的出现(但我希望该排序是随机的)。我想也许某种自动增量会起作用,但我有多个键,因此需要多列(我相信只允许一个自动增量)。
我想出的解决方案似乎不起作用。首先,我创建了一个新表来存储我感兴趣的列,以及一个额外的列rnd
. 我rnd
稍后会ORDER BY rand()
在需要实际列而不是函数的上下文中使用。这是我如何完成第一点:
SET @rnd = 0;
INSERT INTO new_table SELECT col1, ..., colN, @rnd := @rnd+1 FROM original_table ORDER BY rand();
Run Code Online (Sandbox Code Playgroud)
接下来,我将根据键添加一个自动增量,并使用rnd
我刚刚创建的列。在ALTER TABLE...ORDER BY
不通过函数(如允许排序rand()
),所以这就是为什么我需要创建的rnd
第一列:
ALTER TABLE new_table ADD first_index INT UNSIGNED NOT NULL AUTO_INCREMENT, ADD KEY(col1, col2, first_index), ORDER BY rnd;
Run Code Online (Sandbox Code Playgroud)
然后我会删除自动增量状态并为每个键重复:
ALTER TABLE new_table MODIFY COLUMN first_index INT UNSIGNED NOT NULL;
Run Code Online (Sandbox Code Playgroud)
起初,这似乎奏效了。然而,仔细检查后,似乎没有遵守随机排序。索引列的创建顺序与原始表碰巧使用的顺序相同。当我经历了几个非常尴尬的步骤以确保随机排序时,我感到相当沮丧,而这甚至不起作用。为什么我的解决方案不起作用,有没有更优雅的方法来做到这一点?
编辑:显然我不清楚我在找什么,所以我会尝试一个简单的例子:
Col1 Col2 <other columns>
1997 A
1997 B
2001 B
1997 A
2001 B
1997 A
2001 A
1997 B
Run Code Online (Sandbox Code Playgroud)
上述排序反映了既不是真正可预测的也不是真正随机的原始排序。添加我的rnd
列并按它排序后,我会有这样的事情:
Col1 Col2 <other columns> rnd
1997 B 1
2001 A 2
1997 B 3
2001 B 4
1997 A 5
1997 A 6
1997 A 7
2001 B 8
Run Code Online (Sandbox Code Playgroud)
然后我会得到这样的第一个索引:
Col1 Col2 <other columns> rnd first_index
1997 B 1 1
2001 A 2 1
1997 B 3 2
2001 B 4 1
1997 A 5 1
1997 A 6 2
1997 A 7 3
2001 B 8 2
Run Code Online (Sandbox Code Playgroud)
所以 1997 年 B 出现了 2 次,因此这些值从 1-2 编号,而 1997 年 A 出现了 3 次,因此这些值行编号为 1-3。我使用了ORDER BY rnd
1997-A 的哪一行被分配了索引 1,哪一行得到了 2,哪一行得到了 3(当然,在初始分配之后这将是确定性的)。
编辑:我将添加另一个示例,因为我的目标似乎不清楚。MySQL 文档显示了一种几乎可以到达的方法:
CREATE TABLE animals (
grp ENUM('fish','mammal','bird') NOT NULL,
id MEDIUMINT NOT NULL AUTO_INCREMENT,
name CHAR(30) NOT NULL,
PRIMARY KEY (grp,id)
) ENGINE=MyISAM;
INSERT INTO animals (grp,name) VALUES
('mammal','dog'),('mammal','cat'),
('bird','penguin'),('fish','lax'),('mammal','whale'),
('bird','ostrich');
SELECT * FROM animals ORDER BY grp,id;
Run Code Online (Sandbox Code Playgroud)
这将创建一个表,虽然不是我想要的,但它很接近:
+--------+----+---------+
| grp | id | name |
+--------+----+---------+
| fish | 1 | lax |
| mammal | 1 | dog |
| mammal | 2 | cat |
| mammal | 3 | whale |
| bird | 1 | penguin |
| bird | 2 | ostrich |
+--------+----+---------+
Run Code Online (Sandbox Code Playgroud)
这很接近,但我认为这对我不起作用至少有两个原因。首先,我需要在现有表上执行此操作,而不是在我正在创建的表上执行此操作。其次,我不想仅仅因为它在底层表中dog
首先出现在mammal
组中。有一次,我想随机化该顺序。从那时起,排序将是确定性的,但我希望它首先是随机的。
如果你想知道我想要这样做的动机,这里有一个问题解释了我想用这个做什么。另请注意,解决方案应在 MySQL 中。
这就是我要做的。我希望我正确理解了你的问题。这是一种解决方法,也许不是很优雅:
SELECT
MIN(ID) AS MIN_ID, Col1, Col2
FROM
table
GROUP BY
Col1, Col2
Run Code Online (Sandbox Code Playgroud)
UPDATE
table t, temp_table tmp
SET
t.first_index = (t.ID - tmp.MIN_ID) + 1
WHERE
t.Col1=tmp.Col1 AND t.Col2=tmp.Col2
Run Code Online (Sandbox Code Playgroud)
归档时间: |
|
查看次数: |
5531 次 |
最近记录: |