2017-07-30 115 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