[英]Inserting a number in a sequence with missing numbers
I have a table containing info of tree nodes.我有一个包含树节点信息的表。
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
I need to copy all elements from root_id
2 into root_1
.我需要将所有元素从
root_id
2 复制到root_1
。 But, if element_type_id
and number
matches, the inserting element must be renumbered into a minimal free number of sequence 1..99.但是,如果
element_type_id
和number
匹配,则插入元素必须重新编号为序列 1..99 的最小空闲数。 For example: the first one has numbers 1,2,5.例如:第一个有数字 1,2,5。 The second one - 1,2,3.
第二个 - 1,2,3。 The result must be 1,2,3,4,5,7.
结果必须是 1,2,3,4,5,7。
To generate "free numbers" i could do like this:要生成“免费号码”,我可以这样做:
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;
But I don't realize how to get it work within copy query (whatever it is. cause i don't know that either).但我不知道如何让它在复制查询中工作(不管它是什么。因为我也不知道)。
How do I do that?我怎么做? How to solve the problem by using PostgreSQL?
如何使用 PostgreSQL 解决问题? Which way to dig?
用什么方法挖? Does PostgreSQL have similar functions?
PostgreSQL有类似的功能吗? Or may be I have to use loops, inner loops etc.?
或者我可能必须使用循环、内循环等?
I'll present the following, it does not reproduce you requested result exactly, but it does satisfy the "minimal free number of sequence" requirement.我将介绍以下内容,它不会准确地重现您请求的结果,但它确实满足“最小自由序列数”的要求。 Which by-the-way your request does not if your intent is creating a dense sequence.
顺便说一句,如果您的意图是创建密集序列,则您的请求不会。
It builds 2 CTEs, avail_numbers and merge_numbers: Avail_numbers starts with "free numbers" generator taking these as cardinal values, it then appends to this set a ordinal number indicating the sequence the cardinal numbers are to be assigned.它构建了 2 个 CTE,avail_numbers 和 merge_numbers:Avail_numbers 以“空闲数字”生成器开始,将它们作为基值,然后在该集合中附加一个序数,指示要分配基数的顺序。 Ie the generator produces produces a set 3,4,6, ... The ordinal assignment transforms this into a set (1,3), (2,4), (3,6).
即生成器产生一个集合 3,4,6, ... 序数分配将其转换为一个集合 (1,3), (2,4), (3,6)。 Meaning the first value to use is 3, the second value to use in 4, etc. Merge_numbers is built in a similar fashion, extracting the existing "numbers" as cardinal values and generating ordinals resulting in sets as (1,1),(2,2),(3,7)...
这意味着要使用的第一个值是 3,使用 4 中的第二个值等。 Merge_numbers 以类似的方式构建,将现有的“数字”提取为基值并生成序数,结果集为 (1,1),( 2,2),(3,7)...
These sets are then joined on the ordinals producing the set (3,1),(4,2),(7,6) meaning on the merging set update to 3 where current value is 1... (this is where the difference to requested comes in as it update "number" from 7 to 6.然后将这些集合连接到序数上,生成集合 (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;
There is another issue however.然而还有另一个问题。 What happens when the total rows in the 2 root_id,element_type_id combination is 100 or greater.
当 2 root_id,element_type_id 组合中的总行数为 100 或更大时会发生什么。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.