使用另一个表中的随机值更新MySQL表的最佳方法

使用另一个表中的随机值更新MySQL表的最佳方法,mysql,Mysql,对于这个(伪代码)示例,我在MySQL中有两个表: member { id, name } names { name } 共有100名会员和10名会员。我想使用名称中的随机名称来更新成员表。到目前为止,我已经做到了这一点,但是,不确定是否有更好的方法来实现它 UPDATE member SET name = (SELECT name FROM names ORDER BY RAND() LIMIT 1); 代码将从脚本执行,因此我希望避免使用函数等 提前感谢。您可以通过在名称表中添加id列并

对于这个(伪代码)示例,我在MySQL中有两个表:

member { id, name }
names { name }
共有100名会员和10名会员。我想使用名称中的随机名称来更新成员表。到目前为止,我已经做到了这一点,但是,不确定是否有更好的方法来实现它

UPDATE member SET name = (SELECT name FROM names ORDER BY RAND() LIMIT 1);
代码将从脚本执行,因此我希望避免使用函数等


提前感谢。

您可以通过在名称表中添加id列并使用以下命令来避免按兰德()排序:

UPDATE member SET name = (SELECT name FROM names WHERE id=floor(1 + rand()*10 ) );
如果只使用10个名称,结果不会快很多,但是如果您想从更大的名称集中进行选择,则会看到不同之处,因为按rand()排序的效率非常低,而且您对成员中的每一行都这样做

更新: 好像里面的rand()给出了不可预测的结果。 改用这个:

UPDATE member m1
JOIN ( select id, floor(1+rand()*10) as rnd from member ) m2 on m1.id=m2.id
JOIN names n on n.id = m2.rnd
SET m1.name=n.name

受影响的行数可能会有所不同,如果随机名称与表中已存在的行数匹配,则不算作更新。

尝试改进piotrm的解决方案。似乎有效;-)


我觉得不错。只需检查MySQL中的行为-确保子选择实际上为您提供了一个随机名称,而不是对整个集合使用一个随机值。+1尼斯:我之前一直在寻找类似的东西!这基本上是可行的,但是,每隔几次,它就会返回NULL而不是值。查看控制台日志,它显示“子查询返回多行”-我已经检查了id,它们是auto_inc,并且是唯一的。我已经尝试将10调整为9,正如mysql文档建议的那样,应该是*(j-I),但仍然是一样的。有什么想法吗?更新的答案,Devart的解决方案也很好,受影响的行数因相同的原因而不同。仍然是相同的问题。如果创建所有表并运行更新,则会填充所有表。但是,如果只重新运行update语句并查看更新的行数,则会出现各种情况。我需要让所有15条记录都获得新名称。是的,15行已更新,但并非所有行都获得新值。。。我认为所有行都可以通过存储函数进行更新。
CREATE TABLE member (
  id INT(11) NOT NULL AUTO_INCREMENT,
  name VARCHAR(255) DEFAULT NULL,
  PRIMARY KEY (id)
);

CREATE TABLE names (
  id INT(11) NOT NULL AUTO_INCREMENT,
  name VARCHAR(255) DEFAULT NULL,
  PRIMARY KEY (id)
);

INSERT INTO member VALUES 
  (1, NULL),
  (2, NULL),
  (3, NULL),
  (4, NULL),
  (5, NULL),
  (6, NULL),
  (7, NULL),
  (8, NULL),
  (9, NULL),
  (10, NULL),
  (11, NULL),
  (12, NULL),
  (13, NULL),
  (14, NULL),
  (15, NULL);

INSERT INTO names VALUES 
  (1, 'text1'),
  (2, 'text2'),
  (3, 'text3'),
  (4, 'text4'),
  (5, 'text5'),
  (6, 'text6'),
  (7, 'text7'),
  (8, 'text8'),
  (9, 'text9'),
  (10, 'text10');

UPDATE
  member m1
  JOIN (SELECT id, @i:=FLOOR(1 + RAND() * 10), (SELECT name FROM names n WHERE n.id = @i) name FROM member) m2
    ON m1.id = m2.id
SET
  m1.name = m2.name;