Reputation: 45
I have to create a dummy data. I already have >30000 features in 'buildings' table, and I created 1 new column called 'roof_material' . I also have another table called 'materials' which contains 8 rows, like this:
|id| material
+--+-----------
|1 | tiles
|2 | metal
|3 | concrete
|4 | slate
|5 | steel
|6 | clay
|7 | wood shake
|8 | asphalt
I want to populate the buildings.roof_materials with values from "materials" table randomly.
So in the end, every row in that 30000 features will have roof_materials data.
Can anyone help me?
Upvotes: 0
Views: 100
Reputation: 1269463
This can be tricky, because sometimes Postgres optimizations get in the way. One method uses a lateral join (or correlated subquery):
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
The correlation clause (the where
) is important because otherwise Postgres decides that it can run the subquery only once.
If you want an equal distribution of the values, then you can randomly enumerate each list and join them using modulo arithmetic:
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 is a db<>fiddle.
Upvotes: 0
Reputation:
Assuming that the column roof_material
is a foreign key to the material
table, you can simply do this:
update buildings
set roof_material = (random() * 7 + 1)::int;
That essentially hard codes the possible primary key values of the material
table - which is good enough for a one-off update.
If you want to make that dynamic depending on the actual values in the material
table you can use something like this:
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;
First the common table expression idlist
collects all existing IDs from the material
table into an array and the update statement then randomly picks elements from that array when updating the building table.
Upvotes: 1