繁体   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