oracle 显示数字范围-以字母字符为前缀

7hiiyaii  于 2022-12-26  发布在  Oracle
关注(0)|答案(2)|浏览(130)

Oracle数据库19c企业版
我有一个表,上面有各种代码,如下所示。代码前面有一个字母,后面跟着一个数字。有些是按顺序排列的,有些是单独的或随机的独立数字。

A1,A2,A3,A4,A5,A8,A9,A10,A11,A12,B3,B5,B7,B8,B9,B110,B111,B112,C1,C2,C3,C4,C5,C6,C7,C8

我希望按如下所示的范围显示它们。下面是指向架构和数据的链接:SQL小提琴
预期输出:

A1-A5  
A8-A12  
B3  
B5  
B7-B9  
B110-B112  
C1-C8

我尝试了http://lalitkumarb.wordpress.com/2015/07/22/find-range-of-consecutive-values-in-a-sequence-of-numbers-or-dates/这样的解决方案,但对我不起作用,因为我在数字前加了字母前缀。

gudnpqoy

gudnpqoy1#

在Oracle 12中,可以将字符串拆分为前缀和后缀,然后使用MATCH_RECOGNIZE高效地执行逐行模式匹配:

SELECT prefix || first_suffix || '-' || prefix || last_suffix AS range
FROM   (
  SELECT TRANSLATE(ref_code, 'A0123456789', 'A') AS prefix,
         TO_NUMBER(TRANSLATE(ref_code, '0ABCDEFGHIJKLMONPQRSTUVWXYZ', '0')) AS suffix
  FROM   xx_ref_codes
)
MATCH_RECOGNIZE(
  PARTITION BY prefix
  ORDER BY suffix
  MEASURES
    FIRST(suffix) AS first_suffix,
    LAST(suffix) AS last_suffix
  PATTERN (consecutive* final_row)
  DEFINE consecutive AS suffix + 1 = NEXT(suffix)
);

或者,如果要使用分析函数,然后进行聚合,则:

SELECT prefix || MIN(suffix) || '-' || prefix || MAX(suffix) AS range
FROM   (
  SELECT prefix,
         suffix,
         suffix - ROW_NUMBER() OVER (PARTITION BY prefix ORDER BY suffix) AS grp
  FROM   (
    SELECT TRANSLATE(ref_code, 'A0123456789', 'A') AS prefix,
           TO_NUMBER(TRANSLATE(ref_code, '0ABCDEFGHIJKLMONPQRSTUVWXYZ', '0')) AS suffix
    FROM   xx_ref_codes
  )
)
GROUP BY prefix, grp

对于示例数据,这两个函数都输出:
| 范围|
| - ------|
| A1至A5|
| A8至A12|
| B3-B3|
| B5-B5|
| B7-B9|
| 小行星110 - 112|
| 碳1-碳8|
fiddle

nszi6y05

nszi6y052#

也可以使用标准SQL解决:

select header || min(num) || case when min(num) <> max(num) then '-' || header || max(num) end as result 
from (
    select substr(ref_code,1,1) as header, to_number(substr(ref_code,2)) as num,
        to_number(substr(ref_code,2)) - row_number() over(partition by substr(ref_code,1,1) order by to_number(substr(ref_code,2))) as grp, ref_code
    from xx_ref_codes
)
group by header, grp
;

A1-A5
A8-A12
B3
B5
B7-B9
B110-B112
C1-C8

相关问题