在缺少数字的序列中插入数字

我有一个包含树节点信息的表。

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,3。结果必须是1,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有类似的功能吗?还是我必须使用循环,内部循环等?

wolflaw 回答:在缺少数字的序列中插入数字

我将介绍以下内容,它不能完全重现您请求的结果,但是确实满足“最小自由序号”要求。如果您的意图是创建密集的序列,那么您的请求不会选择哪种方式。
它建立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。

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或更大时,会发生什么情况。

本文链接:https://www.f2er.com/2414897.html

大家都在问