postgresql -在检查条件是否满足的同时,随机将行从一个表插入到另一个表

yrefmtwq  于 2023-08-04  发布在  PostgreSQL
关注(0)|答案(1)|浏览(134)

我有一个tableA,它包含一个id、一个weight(int)和其他类别字段,我必须过滤它们。权重越低,被复制到表B的概率越高。
我必须复制一定数量的行(125),并且必须确保表B中满足某些条件:

  • 至少5行fieldA = 'value1' and fieldB = 'value10'
  • 至少5行fieldA = 'value1' and fieldB = 'value11'
  • 至少1行fieldA = 'value2'
  • 还有其他大致相同的条件。

选择行并不是一个真正的问题:

insert into tableB (id, weight, fieldA, fieldB)
select id, weight, fieldA, fieldB
from tableA
where 
    (fieldA = 'value1' and fieldB = 'value10')
    or (fieldA = 'value1' and fieldB = 'value11')
    or (fieldA = 'value2')
order by random() * weight

字符串
但是,由于表B中填充的是“随机”值,我如何确保满足最低条件?我需要在一个循环中这样做吗?我猜是的:插入一行、检查条件,然后插入另一行、检查条件,依此类推。以前没有在SQL中做过循环,希望有一些指导。
谢谢你,谢谢

6l7fqoea

6l7fqoea1#

ROW_NUMBER加上一些额外的逻辑是你的朋友。
这里的前景

  • 为您的每一个条件定义(例如,fieldA = 'value1' and fieldB = 'value10')a uniquethread_id
  • 对于每个 * 线程 *,相对于降序weight定义row_number-即partition by thread_id order by weight desc
  • 只保留所需的最小数量的row_number(例如5为上面的线程)
  • 选择所有具有row_number的行,并按降序weight-order by rn nulls last, weight desc选择限制的其他行

当然,只有当表具有每个线程所需的最小行数,并且最小行数的总和小于您的总体限制时,它才能工作。

查询

with ta as (
select 
 a.*,
 case /* your conditions here */
 when fieldA = 'value1' and fieldB = 'value10' then 1
 when fieldA = 'value1' and fieldB = 'value11' then 2
 when fieldA = 'value2' then 3
 end as thread_id
from tableA a
), ta2 as (
select 
 ta.*,  /* add index rn for each thread */
 row_number ()  over (partition by thread_id order by weight desc) rn
from ta
)
select 
  id, fielda, fieldb, weight, thread_id,
  case /* keep rn for the required counts */
  when thread_id in (1,2) and rn <= 5 or 
       thread_id = 3 and rn <= 1 
  then rn   end as rn
from ta2
order by 6 nulls last, weight desc 
limit 125

字符串

样本数据

create table tableA as
select 
id,
'value'|| floor(random() * 12 + 1)::text as fieldA,
'value'|| floor(random() * 12 + 1)::text as fieldb,
random() weight
from generate_series(1,100000) t(id)

结果

id   |fielda |fieldb |weight            |thread_id|rn|
-----+-------+-------+------------------+---------+--+
75078|value2 |value5 | 0.999945197714716|        3| 1|
69603|value1 |value10|0.9981664255434559|        1| 1|
90845|value1 |value11|0.9961481124707383|        2| 1|
98661|value1 |value10| 0.995685359324316|        1| 2|
73730|value1 |value11|0.9943281590439526|        2| 2|
20895|value1 |value10|0.9948395132030576|        1| 3|
28411|value1 |value11|0.9926846343501374|        2| 3|
 6689|value1 |value10|0.9926810486253324|        1| 4|
26683|value1 |value11|0.9896049495594461|        2| 4|
52026|value1 |value10|0.9915162874600227|        1| 5|
48511|value1 |value11|0.9881885052326673|        2| 5|
42838|value8 |value2 |0.9999986646619519|         |  |
93206|value3 |value12|0.9999955774933724|         |  |
39188|value8 |value8 |0.9999941396240928|         |  |
54205|value7 |value8 | 0.999971846101122|         |  |
...

相关问题