考虑一个名为 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))
由于有了这些评论,我意识到我最初的问题缺少一个基本原理。
谢谢。
答案 0 :(得分:1)
我认为这将满足您的要求
UPDATE data_records
SET C2 = random();
我不确定为什么要使用子查询或generate_series()
。
答案 1 :(得分:1)
仅使用random
函数,无需任何子查询
update t
set C2 = random()
答案 2 :(得分:1)
用于JSON的简单方法是:
UPDATE
data_records dr
SET
c2 = jsonb_set(dr.c2, '{variation}', to_jsonb(random()));
如果您希望第二列带有generate_series
(无论如何),则需要在原始表上加入一些内容。 generate_series
可以为您提供从1
到5
的行。因此,要加入data_records
,您也需要在1
至5
列中加入。如果这是c1
中保存的内容,那就没有问题。只需加入c
1即可。
但是,如果不是必须生成的话,也许可以使用row_number
窗口函数来将行计数添加为列。然后,您可以将行计数加入到generated_series
列中,并且每个random
和c1
都有一个带有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列,那实际上会更简单。但是,尽管如此,我看不出有什么理由使它变得如此复杂。