You can achieve this using a virtual layer.
Go to the menu Layer > Add Layer > Add/Edit Virtual Layer...
and enter the following query. Feel free to add/remove any field of interest from the two layers.
This query makes use of the fact that in SQLlite a group by
without an aggregator (min
, max
etc) will return values of the "first" row. By specifying a random order in the subquery, we effectively get a random point per polygon.
You can then export the virtual layer to a shapefile or else. Note that each time you pan the map the virtual layer is recomputed and therefore a different random point will be selected.
select *
from
(
select a.id as poly_id, b.*
from mypoly_layer a
join mypoint_layer b
on st_intersects(a.geometry, b.geometry)
order by random()
)
group by poly_id