我有一个表,其中包含,除了其他,这样的领域: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