如何使用随机值更新列中的所有行?

时间:2018-09-21 10:47:19

标签: sql postgresql sql-update

考虑一个名为 data_records 的表,该表具有 5条记录 2列(C1和C2)。

目标是用不同的随机值更新 C2 列的所有行。

以下内容无效:

UPDATE data_records SET
  C2 = d.r
FROM
  (SELECT random() as r, generate_series(1, 5) as g) as d

因为它用相同的编号更新C2的所有行。

子查询

SELECT random() as r, generate_series(1, 5) as g

但是,当单独执行时会生成我想要的表,即每行一个随机值。

如何获得我描述的行为?

更新

我尝试使用子查询进行更新的原因是因为我遇到了我的目标列类型为 jsonb 的情况。 我的SET子句看起来像这样:

SET C2 = jsonb_set(C2, '{variation}', to_jsonb(d.r))

由于有了这些评论,我意识到我最初的问题缺少一个基本原理。

谢谢。

3 个答案:

答案 0 :(得分:1)

我认为这将满足您的要求

UPDATE data_records
    SET C2 = random();

我不确定为什么要使用子查询或generate_series()

答案 1 :(得分:1)

仅使用random函数,无需任何子查询

update t
   set C2 = random() 

答案 2 :(得分:1)

demo: db<>fiddle

用于JSON的简单方法是:

UPDATE 
    data_records dr
SET 
    c2 = jsonb_set(dr.c2, '{variation}', to_jsonb(random()));

如果您希望第二列带有generate_series(无论如何),则需要在原始表上加入一些内容。 generate_series可以为您提供从15的行。因此,要加入data_records,您也需要在15列中加入。如果这是c1中保存的内容,那就没有问题。只需加入c 1即可。

但是,如果不是必须生成的话,也许可以使用row_number窗口函数来将行计数添加为列。然后,您可以将行计数加入到generated_series列中,并且每个randomc1都有一个带有c2值的行。其中之一应该是唯一的。此唯一列(在我的情况下为c1)用作WHERE子句的UPDATE过滤器。当然,这可能是c2。但是,如果它们不是唯一的,那么对于相同的random值,您将以相同的c1/c2值结尾:

UPDATE 
    data_records dr
SET 
    c2 = jsonb_set(dr.c2, '{variation}', to_jsonb(rand.r))
FROM 
    (SELECT *, row_number() OVER () rn FROM data_records) dr_rn
LEFT JOIN
    (SELECT generate_series(1, 5) gs , random() r) rand 
ON dr_rn.rn = rand.gs

WHERE dr.c1 = dr_rn.c1;

如果您有一个唯一的id列,那实际上会更简单。但是,尽管如此,我看不出有什么理由使它变得如此复杂。