2017-07-30 97 views
1

我要求Microsoft SQL Server和PostgreSQL的类似的问题的随机行复制多个值。在那里工作的解决方案不适用于MySQL。MySQL的:从另一个表

我有两个表,stuffnonsense。我想多个值从随机排nonsensestuff复制到每一行。当然,会有重复。

STUFF 
+----+---------+-------------+--------+ 
| id | details | data  | more | 
+====+=========+=============+========+ 
| 1 | one  | (null)  | (null) | 
| 2 | two  | (null)  | (null) | 
| 3 | three | (null)  | (null) | 
| 4 | four | (null)  | (null) | 
| 5 | five | (null)  | (null) | 
| 6 | six  | (null)  | (null) | 
+----+---------+-------------+--------+ 

NONSENSE 
+----+---------+-------------+ 
| id | data | more  | 
+====+=========+=============+ 
| 1 | apple | accordion | 
| 2 | banana | banjo  | 
| 3 | cherry | cor anglais | 
+----+---------+-------------+ 

我希望能够复制到stuff表的东西,如:

UPDATE stuff SET data=?,more=? 
FROM ? 

我想获得像下面这样:

+-----+----------+---------+-------------+ 
| id | details | data | more  | 
+=====+==========+=========+=============+ 
| 1 | one  | banana | banjo  | 
| 2 | two  | apple | accordion | 
| 3 | three | apple | accordion | 
| 4 | four  | cherry | cor anglais | 
| 5 | five  | banana | banjo  | 
| 6 | six  | cherry | cor anglais | 
+-----+----------+---------+-------------+ 

这里是一个小提琴其中工程对PostgreSQL:如果它是一个单一VA http://sqlfiddle.com/#!17/313fb/8

lue,我可以使用相关的子查询,但对于来自同一行的多个值无法正常工作。

较新的PostgreSQL有从相关子查询复制到多列的能力。 SQL Server的OUTER APPLY子句允许FROM子句中的子查询相关联。这两种方法都不适用于MySQL。

我怎样才能在另一个表从随机行复制多个值吗?

+0

显示预期结果请 – scaisEdge

+0

@scaisEdge请参阅编辑。小提琴在这里:http://sqlfiddle.com/#!17/313fb/8 – Manngo

回答

0

如果你只需要做一次,不关心真正的随机,也许发明一个函数,它以某种方式映射stuff.id到nonsense.id? 例如:

update stuff s, nonsense n 
set s.data = n.data, s.more = n.more 
where n.id = s.id + 1 or n.id = ceil(s.id/2) -1; 

看起来很像疯狂随机给我;)

http://sqlfiddle.com/#!9/dd0935/1

附:现在,是严重的......不能试穿sqlfiddle,但如果你有机会到MySQL版本8.0或更高版本,你可以尝试水木清华这样的:

with rn as (select n.data, n.more from stuff s, nonsense n order by rand()) 
update stuff, rn 
set stuff.data = rn.data, stuff.more = rn.more; 

UPDATE:一些合作头脑风暴两次变化后发现

update stuff s 
join (select id,(select id from nonsense order by rand() limit 1) as nid from stuff) sq on s.id=sq.id 
join nonsense n on n.id = sq.nid 
set s.data = n.data, s.more = n.more; 


update stuff s 
join (select * from (select s.id as sid, n.data as sdata, n.more as smore from stuff s, nonsense n order by rand()) sn group by sn.sid) sgr on s.id = sgr.sid 
set s.data = sgr.sdata, s.more = sgr.smore; 
1

惨不忍睹,但我认为这是一个解决方案。

与该stuff.id虚拟表和随机nonsense.id开始:

select id,(select id from nonsense order by rand() limit 1) as nid from stuff; 

与此虚拟表加入stuff表作为一个子查询:

stuff s 
join 
(select id,(select id from nonsense order by rand() limit 1) as nid from stuff) sq 
on s.id=sq.id 

更新s.datas.more与相关子查询:

set 
    s.data=(select data from nonsense where id=sq.nid), 
    s.more=(select more from nonsense where id=sq.nid); 

这给:

update 
    stuff s 
    join 
    (select id,(select id from nonsense order by rand() limit 1) as nid from stuff) sq 
    on s.id=sq.id 
set 
    s.data=(select data from nonsense where id=sq.nid), 
    s.more=(select more from nonsense where id=sq.nid); 

应该有一个平滑的解决方案,但是这是我能做到的最好。

+0

太棒了!也许在废话上多加一个连接,所以摆脱两个相关的子查询会提高执行时间?更新 东西s 加入 (选择编号,(从无限顺序选择编号由rand()限制1)作为nid从东西)平方 在s.id = sq.id 加入无义n上n.id = sq。 nid set s.data = n.data,s.more = n.more; –

+0

只是发明了另一个,但它可能不是一个很大的改进...你应该检查大数据:更新的东西s加入 (select * from (select s.id as sid,n.data as sdata,n。更多的东西s,废话n秩序rand())sn group by sn.sid)sgr on s.id = sgr.sid set s.data = sgr.sdata,s.more = sgr.smore ; –

+0

@InnaTichman我已经尝试了这两种解决方案,并且它们非常好。第二个依赖于一个非标准的MySQL扩展到'GROUP BY',但没关系。你能否将这些添加到下面的答案中,以便我可以接受这一切?毕竟,感谢 – Manngo