Oracle SQL从数字字段中找出序号

时间:2018-10-19 16:38:03

标签: sql oracle

我在表中有数字(number(15,0))列。我想查看该列中所有具有序号模式的记录,例如123、5678、654321和所有此类可能的序号模式。最好的SQL是什么?

3 个答案:

答案 0 :(得分:1)

如果我要解决这个问题,我将建立一个表格,列出所有符合条件的数字序列。看来您同时在增加和减少。无论哪种方式。数量有限。然后,我只是在我感兴趣的列与排位赛表之间做一个内部联接。这样避免了逐行操作,并简化了所涉及的SQL。

您可以通过多种方式使用逻辑代码,精美的UDF等来解决此问题,但最终,我认为联接(尤其是利用适当的索引)将是“最佳选择”。我将“最佳”解释为对资源的最有效利用和回报速度。

如果您还想将序列显示为两位数,那么它将不再适用。即123456789101112

答案 1 :(得分:0)

Oracle SQL support regex functions,使用类似: ^(?=\d{15}$)0?1?2?3?4?5?6?7?8?9? 基于:Regular Expression for matching a numeric sequence?

我对Regex并不满意,我不确定您为什么这样做,所以无法提供更好的解决方案。

答案 2 :(得分:0)

在这里整理@RThomas的想法(已投票!):有一张表格,其中包含您要检测的所有序列, 并将内部联接写入要检查的表。以下代码段可能会有所帮助 (已在Oracle 12c上测试)。

包含所有相关模式的表。

drop table patterns ;

create table patterns (
  pattern number primary key
);

匿名块(执行一次)

-- find patterns in the 2 constants (ascending/descending)
-- and insert them into the patterns table
declare
  ascpattern constant char( 9 ) := '123456789' ;
  descpattern constant char( 9 ) := '987654321' ;
begin
  for length in 2 .. 9 
  loop
    for offset in 1 .. 8 
    loop
      if length + offset <= 10 then
        -- dbms_output.put_line ( substr( ascpattern, offset, length ) ) ;
        -- dbms_output.put_line ( substr( descpattern, offset, length ) ) ;
        insert into patterns ( pattern ) 
          values ( to_number( substr( ascpattern, offset, length ) ) ) ;
        insert into patterns ( pattern ) 
          values ( to_number( substr( descpattern, offset, length ) ) ) ;
      end if ;
    end loop ;
  end loop ;
end ;
/

样式表

select * from patterns ;

   PATTERN
----------
        12  -- contained in ascpattern
        21  -- contained in descpattern
        23
        32
        34
...
   9876543
  12345678  -- contained in ascpattern
  23456789  -- contained in ascpattern
  87654321  -- contained in descpattern
  98765432  -- contained in descpattern
 123456789  -- contained in ascpattern
 987654321

72 rows selected.

测试:包含100000个随机整数的表。

drop table randomnumbers ;

create table randomnumbers
as
select trunc( dbms_random.value ( 0, 999999 ) ) randomnumber
from dual
connect by level <= 100000 ;

select * from randomnumbers fetch first 6 rows only ;


RANDOMNUMBER
------------
      529903
      653752
      339231
       42871
      599376
      381709

通过使用内部联接来检测随机数表中的模式。 (当然,您的结果集看起来会有所不同。)

select
  pattern
, randomnumber
from patterns P
  join randomnumbers R on P.pattern = R.randomnumber 
order by pattern ;


   PATTERN RANDOMNUMBER
---------- ------------
        76           76
        87           87
       456          456
      3456         3456
     54321        54321
     56789        56789