在PostgreSQL中用另一个表中另一列的值随机更新表中的一列

pjngdqdw  于 2023-04-20  发布在  PostgreSQL
关注(0)|答案(1)|浏览(150)

我从一个数据生成器网站下载了两个SQL表A和B。假设这两个表都使用std_id列链接(A中的std_id是主键,B中的std_id是外键)。
问题是,我使用UUID生成这些列,A中的std_id都不匹配B中的任何std_id。我想知道如何使用A中的std_id以随机方式从B中更新std_id。我的查询:

do
$$
declare
    ele record;
begin
    for ele in select std_id from B
    loop
    update A
    set std_id = (SELECT std_id FROM student OFFSET floor(random() * 100) LIMIT 1);
    end loop;
end;
$$

其将B中的所有记录的std_id设置为A中的单个std_id。
我应该怎么做才能在B中随机选择不同的std_id(也就是说,在每次循环迭代中,我想要一个来自A的随机std_id,而不是来自A的单个随机std_id)。
感谢您的评分

zzzyeukh

zzzyeukh1#

假设表A包含100行

create table a as
select gen_random_uuid () std_id from generate_series(1,100);

和yout表B包含1000行

create table b as
select gen_random_uuid () std_id from generate_series(1,1000) t(id);

简单地用唯一行号(rn)计算每个A

select 
row_number() over(order by std_id) rn,
std_id
from a

rn |std_id                              |
---+------------------------------------+
  1|03423be8-3da6-48b1-9bdf-a0e40ad1e502|
  2|08d45683-7816-4f57-9802-4967d5215208|
  3|0a23a421-a934-4b73-8ba3-c3a8ac502d62|

并为每个B行分配一个介于1和100之间的随机整数(= A的行连接)

select  trunc(random() * 100 + 1)::int rn,
std_id 
from b

rn |std_id                              |
---+------------------------------------+
 10|29f925b8-1db3-4869-84b3-6b739b54850c|
 79|627ed460-6fcc-4894-8a6d-c29b708df0ec|
 75|0cfbdee6-5dce-4a5a-ab65-092886e0daeb|

请注意,您为B的每一行随机选择了A中唯一的一行,即您定义了FK关系。
现在,简单地在rn上连接上述两个子查询,您将得到一个应该更新的new_std_id(来自A的相关记录的std_id)。
查询

with ta as (
select 
row_number() over(order by std_id) rn,
std_id
from a),
tb as (
select  trunc(random() * 100 + 1)::int rn,
std_id 
from b)
select 
tb.std_id, ta.std_id new_std_id 
from tb
join ta on tb.rn = ta.rn
order by ta.std_id::text
;

std_id                              |new_std_id                          |
------------------------------------+------------------------------------+
33cad288-9b67-4585-b0d1-328381359993|03423be8-3da6-48b1-9bdf-a0e40ad1e502|
3a00c0a2-86d5-4bab-98da-02f49437c5ca|03423be8-3da6-48b1-9bdf-a0e40ad1e502|
...|
f33be20b-3b60-4da4-9e90-90a57684b4e3|03423be8-3da6-48b1-9bdf-a0e40ad1e502|
b40cb769-593a-472c-8ce2-8266683a73f1|08d45683-7816-4f57-9802-4967d5215208|
2ec2f939-55fe-4ebb-bb4b-5f2b14253638|08d45683-7816-4f57-9802-4967d5215208|
...
3204f23b-254a-4cb7-9113-874eee846f03|08d45683-7816-4f57-9802-4967d5215208|
46ee11a3-2ae2-40ee-904a-4a6e3c67a819|0a23a421-a934-4b73-8ba3-c3a8ac502d62|

现在,您已经准备好了一个数据,可以使用 * joinupdate * 更新表B

with ta as (
select 
row_number() over(order by std_id) rn,
std_id
from a),
tb as (
select  trunc(random() * 100 + 1)::int rn,
std_id 
from b),
tab as (
select 
tb.std_id, ta.std_id new_std_id
from tb
join ta on tb.rn = ta.rn
)
update b
set std_id = tab.new_std_id
from tab where b.std_id = tab.std_id

相关问题