我有一個表,其中包含,除了其他,這樣的領域:id integer, status_id integer, add_date date
。如何只更新匹配值的一定百分比
我想執行類似這樣的查詢:
update table set status_id = new_status_id where status_id = old_status_id
而是一個只會更新值的給定的百分比,比如50%。而且,每個日期的更新行的分佈應該是相似的;我想更新date = 23.06.2013
半行,而不是一半。
我有一個表,其中包含,除了其他,這樣的領域:id integer, status_id integer, add_date date
。如何只更新匹配值的一定百分比
我想執行類似這樣的查詢:
update table set status_id = new_status_id where status_id = old_status_id
而是一個只會更新值的給定的百分比,比如50%。而且,每個日期的更新行的分佈應該是相似的;我想更新date = 23.06.2013
半行,而不是一半。
update table
set status_id = new_status_id
where
status_id = old_status_id
and random() < 0.5
該查詢會給你行的id
,要更新:
SELECT *
FROM
(SELECT id,
count(id) OVER (PARTITION BY add_date) cnt,
row_num() OVER (PARTITION BY add_date ORDER BY id) rn
FROM table
WHERE status_id = old_status_id) sub
WHERE rn <= cnt * 0.5 -- your percentage
-- WHERE rn <= cnt * 0.5 + random() -- another (better) version.
-- Will update at random if there if only one row
'ORDER BY id' ..它不在請求中首先更新較小的ID。你可以刪除子句以獲得任意選擇(這會更快,因爲兩個窗口函數共享相同的窗口),或者用'ORDER BY random()'替換它以獲得真正的隨機選擇。 –
@ErwinBrandstetter是的,我知道。這只是一種習慣,將ORDER BY添加到具有任意列的row_num()中(否則Oracle會拋出錯誤)。在不需要時使用'random()'不是很好。 (調用'random()'可能不便宜) –
_if它足夠小,因爲你對我的答案的評論,那麼這也不是完美的,因爲沒有一個只有一行的日期將被刪除。還有一個小錯誤,即count和row_number都返回整數。解決辦法就像'rn :: float/cnt' –
當躺在牀上,並試圖睡一個非常簡單的解決方案來到我的腦海:
update table
set status_id = new_status_id
where
status_id = old_status_id
and id % 2 = 0;
由於id實際上是bigserial
,所以此查詢將與Clodoaldo具有相似的效果。
簡單的,但不會考慮日期。它可以更新整個表(如果它足夠小) –
@IgorRomanchenko關於日期的不精確更新是可以接受的,並且這個查詢是最簡單的可能。因此接受。謝謝你的工作,謝謝。 – Dariusz