[英]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.