oracle 如何根据该行的条件为每个表行获取给定数字之间的下一个可用数字

nzrxty8p  于 2023-11-17  发布在  Oracle
关注(0)|答案(1)|浏览(115)

对于从Oracle DB表中获取每个Product记录,我需要生成给定编号范围内下一个可用编号。在生成下一个编号时,只要给定编号范围内有未使用编号,就不涉及条件检查。当它已经到达给定编号范围内最后一个编号时,它应该从头开始重复,但是从这个时候开始,它应该基于条件检查来生成它。
我将试着用简单的方式表达我的要求。
使用的序列号范围:1-3(1至3)
PRODUCT表中的数据:

Name  Start Date    End Date
P1    1-Nov
P2    1-Nov         5-Nov
P3    1-Nov
P4    2-Nov
p2    2-Nov

字符串
让我们说没有结束日期的产品是活跃的产品,有结束日期的产品是不活跃的产品。
预期输出:

Name  Start Date    End Date    SequenceNumber     Comment
P1    1-Nov                     1                  No conditional check
P2    1-Nov         5-Nov       2                  No conditional check
P3    1-Nov                     3                  No conditional check
P4    2-Nov                     2                  Sequence should start from 1 again but with condition check while generating sequence. Condition: If the generated number is used in any other active product, move on to next number  
p2    2-Nov                                        In this case, all 1, 2, 3 are mapped to active products. so no sequence is generated.


问:如何使用select语句获得所需的输出?这将是有帮助的,如果你能建议一些方法。谢谢。

qqrboqgw

qqrboqgw1#

嗯,它看起来像行间-列间处理,这意味着你可以使用Oracle's MODEL Clause。它的工作原理很像excel工作表寻址单个单元格。

WITH    --  S a m p l e   D a t a :
    tbl AS
        (   Select 'P1' "A_NAME",  Date '2023-11-01' "START_DATE", Null "END_DATE" From Dual Union All
            Select 'P2' "A_NAME",  Date '2023-11-01' "START_DATE", Date '2023-11-05' "END_DATE" From Dual Union All
            Select 'P3' "A_NAME",  Date '2023-11-01' "START_DATE", Null "END_DATE" From Dual Union All
            Select 'P4' "A_NAME",  Date '2023-11-02' "START_DATE", Null "END_DATE" From Dual Union All
            Select 'P2' "A_NAME",  Date '2023-11-02' "START_DATE", Null "END_DATE" From Dual 
        )
--  M a i n    S Q L :
SELECT    A_NAME, START_DATE, END_DATE, SEQUENCE_NUMBER
FROM    ( Select  ROWNUM "RN", A_NAME, START_DATE, END_DATE, 0 "SEQUENCE_NUMBER"
          From    tbl
        )
             -- RowNum (RN) used to uniquely identify rows
        MODEL   Dimension By ( RN )
                Measures ( A_NAME, START_DATE, END_DATE, SEQUENCE_NUMBER, 0 "SEQUENCES" )
        RULES
            ( SEQUENCE_NUMBER[ANY] =  Case When   Case  When Nvl(Count(START_DATE)[RN < CV()], 0) + 1 <= 3 
                                                        Then Nvl(Count(START_DATE)[RN < CV()], 0) + 1 
                                                  Else 0 End = 0
                                              Then  0
                                      Else   Case When Nvl(Count(START_DATE)[RN < CV()], 0) + 1 <= 3 
                                                  Then Nvl(Count(START_DATE)[RN < CV()], 0) + 1   -- this gives non conditional sequences (1 - 3)
                                             Else 0 End
                                      End,
                  --
               -- added colummn SEQUENCES to control the sequence numbers used before the current row
                  SEQUENCES[ANY] = Nvl(Max(SEQUENCE_NUMBER)[RN < CV(RN)], 0),
                  --
                  SEQUENCE_NUMBER[ANY] = Case When SEQUENCE_NUMBER[CV()] = 0
                                              Then Case When SEQUENCES[CV()] = 3 And 
                                                             Min(SEQUENCE_NUMBER)[RN < CV()] = 1 And
                                                             Max(SEQUENCES)[RN < CV()] < 3
                                                        Then Min(SEQUENCE_NUMBER)[RN < CV()] + 1  -- this gives conditional sequence when first is used (used + 1)
                                                   End  -- no Else part (same as Else Null) gives Null when (used + 1) is also done
                                         Else SEQUENCE_NUMBER[CV()]
                                         End
                )
/*    R e s u l t :
A_NAME START_DATE END_DATE  SEQUENCE_NUMBER                            
------ ---------- --------- --------------- 
P1     01-NOV-23                          1 
P2     01-NOV-23  05-NOV-23               2 
P3     01-NOV-23                          3 
P4     02-NOV-23                          2 
P2     02-NOV-23                             */

相关问题