如何将数据从表插入Postgres列

时间:2019-09-20 09:00:53

标签: sql postgresql

我必须创建一个虚拟数据。我在'buildings'表中已经具有30000多个要素,并创建了1个新列'roof_material'。 我还有另一个名为“ materials”的表,其中包含8行,如下所示:

|id|  material
+--+-----------
|1 |  tiles
|2 |  metal
|3 |  concrete
|4 |  slate
|5 |  steel
|6 |  clay
|7 |  wood shake
|8 |  asphalt

我想用“材料”表中的值随机填充building.roof_materials。

最后,这30000个要素中的每一行都将具有roof_materials数据。

有人可以帮助我吗?

2 个答案:

答案 0 :(得分:1)

假设列roof_materialmaterial表的外键,您可以简单地执行以下操作:

update buildings
  set roof_material = (random() * 7 + 1)::int;

从本质上讲,这是对material表的可能主键值进行硬编码的方法-对于一次更新就足够了。

如果您想根据material表中的 actual 值来使它动态化,则可以使用以下方法:

with idlist as (
  select array_agg(id) mat_ids
  from material 
)
update building
  set roof_material = mat_ids[(random() * (cardinality(mat_ids) - 1) + 1)::int]
from idlist;

首先common table expression idlistmaterial表中所有现有的ID收集到一个数组中,然后update语句在更新建筑表时从该数组中随机选择元素。

答案 1 :(得分:0)

这可能很棘手,因为有时Postgres优化会遇到麻烦。一种方法使用横向联接(或相关子查询):

select gs.x, m.*
from generate_series(1, 100) gs(x) cross join lateral
     (select m.*
      from materials m
      where gs.x is not null
      order by random()
     ) m

相关子句(where)很重要,因为否则Postgres决定它只能运行一次子查询。

如果您希望值的均等分布,则可以随机枚举每个列表,并使用取模算法将它们连接起来:

with t as (
      select gs.x, row_number() over (order by random()) - 1 as seqnum
      from generate_series(1, 100) gs(x)
     ),
     m as (
      select m.*, row_number() over (order by random()) - 1 as seqnum,
             count(*) over () as num_materials
      from materials m
     )
select t.x, m.id, m.material
from t join
     m
     on t.seqnum % m.num_materials = m.seqnum
order by t.x;

Here是db <>小提琴。