update dataset1.test
set column4 = (select column1
from dataset2
order by random()
limit 1
)
我必須更新第4列的dataset1,每行更新從數據集2列的隨機條目..但到目前爲止,在上面的查詢中,我只有一個隨機條目在所有數據集1的行及其所有我想要它隨機的相同。從另一個表填充隨機數據
update dataset1.test
set column4 = (select column1
from dataset2
order by random()
limit 1
)
我必須更新第4列的dataset1,每行更新從數據集2列的隨機條目..但到目前爲止,在上面的查詢中,我只有一個隨機條目在所有數據集1的行及其所有我想要它隨機的相同。從另一個表填充隨機數據
SETUP假設你的表的數據是下述的
讓我們開始。 請注意,我假設dataset1
有一個主鍵(也可以是複合的,但爲了簡單起見,讓我們做一個整數):
CREATE TABLE dataset1
(
id INTEGER PRIMARY KEY,
column4 TEXT
) ;
CREATE TABLE dataset2
(
column1 TEXT
) ;
填寫兩個表樣本數據
INSERT INTO dataset1
(id, column4)
SELECT
i, 'column 4 for id ' || i
FROM
generate_series(101, 120) AS s(i);
INSERT INTO dataset2
(column1)
SELECT
'SOMETHING ' || i
FROM
generate_series (1001, 1020) AS s(i) ;
健全檢查:
SELECT count(DISTINCT column4) FROM dataset1 ;
| count | | ----: | | 20 |
我們將執行完整的混洗。來自dataset2的值將被使用一次,但不會超過一次。
說明
爲了使該洗牌的 隨機的方式從column4
所有值的更新,我們需要一些中間步驟。
首先,爲dataset1
,我們需要創建一個元組(id, rn)
列表(關係),即 只是:
(id_1, 1),
(id_2, 2),
(id_3, 3),
...
(id_20, 20)
凡id_1
,...,id_20
是IDS提出關於dataset1
。 它們可以是任何類型的,他們需要的是不連續的,並且它們可以是複合材料。
對於dataset2
,我們需要創建的(column_1,rn)
另一個列表,看起來像:
(column1_1, 17),
(column1_2, 3),
(column1_3, 11),
...
(column1_20, 15)
在這種情況下,第二列包含1 .. 20,但洗牌的所有值。
一旦我們有兩種關係,我們JOIN
他們ON ... rn
。這在實踐中,產生另一個與(id, column1)
元組的列表,其中配對已經隨機進行。我們使用這些配對來更新dataset1
。
THE REAL QUERY
這都是可以做的(顯然,我希望)通過使用一些CTE(WITH
語句)持有中間關係:
WITH original_keys AS
(
-- This creates tuples (id, rn),
-- where rn increases from 1 to number or rows
SELECT
id,
row_number() OVER () AS rn
FROM
dataset1
)
, shuffled_data AS
(
-- This creates tuples (column1, rn)
-- where rn moves between 1 and number of rows, but is randomly shuffled
SELECT
column1,
-- The next statement is what *shuffles* all the data
row_number() OVER (ORDER BY random()) AS rn
FROM
dataset2
)
-- You update your dataset1
-- with the shuffled data, linking back to the original keys
UPDATE
dataset1
SET
column4 = shuffled_data.column1
FROM
shuffled_data
JOIN original_keys ON original_keys.rn = shuffled_data.rn
WHERE
dataset1.id = original_keys.id ;
注意,伎倆通過以下方式執行:
row_number() OVER (ORDER BY random()) AS rn
row_number()
window function,它從1開始產生儘可能多的連續數字,從1開始。 這些數字是隨機洗牌的,因爲OVER
子句獲取所有數據並將其隨機分類。
支票
我們可以再次檢查:
SELECT count(DISTINCT column4) FROM dataset1 ;
| count | | ----: | | 20 |
SELECT * FROM dataset1 ;
id | column4 --: | :------------- 101 | SOMETHING 1016 102 | SOMETHING 1009 103 | SOMETHING 1003 ... 118 | SOMETHING 1012 119 | SOMETHING 1017 120 | SOMETHING 1011
備選
請注意,這也可以通過簡單替換而不是CTE通過子查詢完成。這可能會在某些情況下提高性能:
UPDATE
dataset1
SET
column4 = shuffled_data.column1
FROM
(SELECT
column1,
row_number() OVER (ORDER BY random()) AS rn
FROM
dataset2
) AS shuffled_data
JOIN
(SELECT
id,
row_number() OVER () AS rn
FROM
dataset1
) AS original_keys ON original_keys.rn = shuffled_data.rn
WHERE
dataset1.id = original_keys.id ;
又一次......
SELECT * FROM dataset1;
id | column4 --: | :------------- 101 | SOMETHING 1011 102 | SOMETHING 1018 103 | SOMETHING 1007 ... 118 | SOMETHING 1020 119 | SOMETHING 1002 120 | SOMETHING 1016
您可以在dbfiddle檢查整個設置和實驗here
注意:如果你用非常大的數據集做這件事,不要期望它速度非常快。洗牌很大一套很昂貴。
在這種情況下的行,用於column4
值可以被重複多次。
我能想到的最簡單的可能性(可能,不是一個有效率的,但很容易理解)是創建一個功能random_column1
,標記爲VOLATILE
:
CREATE FUNCTION random_column1()
RETURNS TEXT
VOLATILE -- important!
LANGUAGE SQL
AS
$$
SELECT
column1
FROM
dataset2
ORDER BY
random()
LIMIT
1 ;
$$ ;
並用它來更新:
UPDATE
dataset1
SET
column4 = random_column1();
這樣,從dataset2
一些值可能根本不能使用,而其他將被多次使用。
dbfiddle here
更好是從子查詢引用的外部表。然後,子查詢必須evalued的每一行:
update dataset1.test
set column4 = (select
case when dataset1.test.column4 = dataset1.test.column4
then column1 end
from dataset2
order by random()
limit 1
)
一些問題:你會允許從一個值'dataset2'使用上'dataset1'多次,還是每個值都將最多隻用一次? 'dataset2'是否至少與'dataset1'一樣多? –
[SQl從隨機名稱表更新](https://stackoverflow.com/questions/21560392/sql-update-from-table-of-random-names)可能有重複。假設你在數據集2上有一個數字ID。 – JeffUK
[Redshift:使用另一個表中的隨機數據更新或插入列中的每一行可能的重複](https://stackoverflow.com/questions/45535038/redshift-update-or-insert-each-row-in-column- with-random-data-from-another-tabl) –