簡體   English   中英

在缺少數字的序列中插入一個數字

[英]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_idnumber匹配,則插入元素必須重新編號為序列 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.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM