[英]Inserting a number in a sequence with missing numbers
我有一个包含树节点信息的表。
element_type_id | root_id | parent_id | number_in_parent
4 1 1 1
4 1 1 2
4 1 1 5
4 2 66 1
4 2 66 2
4 2 66 7
我需要将所有元素从root_id
2 复制到root_1
。 但是,如果element_type_id
和number
匹配,则插入元素必须重新编号为序列 1..99 的最小空闲数。 例如:第一个有数字 1,2,5。 第二个 - 1,2,3。 结果必须是 1,2,3,4,5,7。
要生成“免费号码”,我可以这样做:
SELECT "number" FROM (
SELECT generate_series(1, (
SELECT MAX("number") + 99 as "number"
FROM tree_elements te2
WHERE root_id = 1 AND element_type_id = 4)) AS "number"
EXCEPT SELECT "number"
FROM tree_elements te
WHERE root_id = 1 AND element_type_id = 4
) s
ORDER BY "number" LIMIT 99;
但我不知道如何让它在复制查询中工作(不管它是什么。因为我也不知道)。
我怎么做? 如何使用 PostgreSQL 解决问题? 用什么方法挖? PostgreSQL有类似的功能吗? 或者我可能必须使用循环、内循环等?
我将介绍以下内容,它不会准确地重现您请求的结果,但它确实满足“最小自由序列数”的要求。 顺便说一句,如果您的意图是创建密集序列,则您的请求不会。
它构建了 2 个 CTE,avail_numbers 和 merge_numbers:Avail_numbers 以“空闲数字”生成器开始,将它们作为基值,然后在该集合中附加一个序数,指示要分配基数的顺序。 即生成器产生一个集合 3,4,6, ... 序数分配将其转换为一个集合 (1,3), (2,4), (3,6)。 这意味着要使用的第一个值是 3,使用 4 中的第二个值等。 Merge_numbers 以类似的方式构建,将现有的“数字”提取为基值并生成序数,结果集为 (1,1),( 2,2),(3,7)...
然后将这些集合连接到序数上,生成集合 (3,1),(4,2),(7,6),这意味着在合并集合更新为 3 时,当前值为 1...(这就是差异的地方当它把“数字”从 7 更新到 6 时,to requested 进来了。
with avail_numbers(avail_ordinal ,avail_number) as
( select row_number() over(), number_in_parent
from ( select number_in_parent
from ( select generate_series(1, ( select max(number_in_parent) + 99 as number_in_parent
from tree_elements
where root_id = 1
and element_type_id = 4
)
) as number_in_parent
except
select number_in_parent
from tree_elements te
where root_id = 1 and element_type_id = 4
) s
order by number_in_parent limit 99
) n
)
, merge_numbers (merge_ordinal , number_in_parent) as
( select row_number() over(),number_in_parent
from ( select number_in_parent
from tree_elements
where root_id = 2
and element_type_id = 4
order by number_in_parent
) m
)
update tree_elements te
set root_id = 1
, number_in_parent = mseq.avail_number
from (select mn.number_in_parent,an.avail_number
from avail_numbers an
join merge_numbers mn
on (an.avail_ordinal = mn.merge_ordinal )
) mseq
where root_id = 2
and element_type_id = 4
and te.number_in_parent = mseq.number_in_parent;
然而还有另一个问题。 当 2 root_id,element_type_id 组合中的总行数为 100 或更大时会发生什么。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.