Oracle - 将行中的值转换为范围

2022-01-24 00:00:00 sql range oracle

是否有任何技术可以允许这样的行集

Are there any techniques that would allow a row set like this

WITH 
base AS
(
    SELECT  1 N FROM DUAL UNION ALL
    SELECT  2 N FROM DUAL UNION ALL
    SELECT  3 N FROM DUAL UNION ALL

    SELECT  6 N FROM DUAL UNION ALL
    SELECT  7 N FROM DUAL UNION ALL

    SELECT 17 N FROM DUAL UNION ALL
    SELECT 18 N FROM DUAL UNION ALL
    SELECT 19 N FROM DUAL UNION ALL

    SELECT 21 N FROM DUAL
)
SELECT  a.N
FROM base a

产生结果

 1     3
 6     7
17    19
21    21

实际上是从行到范围的操作.我在 Oracle Land 玩游戏,如果有任何建议,我将不胜感激.

It is in effect a rows to ranges operation. I'm playing in Oracle Land, and would appreciate any suggestions.

推荐答案

我觉得这可能可以改进,但它有效:

I feel like this can probably be improved on, but it works:

WITH base AS  (
    SELECT  1 N FROM DUAL UNION ALL
    SELECT  2 N FROM DUAL UNION ALL
    SELECT  3 N FROM DUAL UNION ALL
    SELECT  6 N FROM DUAL UNION ALL
    SELECT  7 N FROM DUAL UNION ALL
    SELECT 17 N FROM DUAL UNION ALL
    SELECT 18 N FROM DUAL UNION ALL
    SELECT 19 N FROM DUAL UNION ALL
    SELECT 21 N FROM DUAL
)
, lagged AS
(
    SELECT n, LAG(n) OVER (ORDER BY n) lag_n FROM base
)
, groups AS
(
    SELECT n, row_number() OVER (ORDER BY n) groupnum
      FROM lagged
      WHERE lag_n IS NULL OR lag_n < n-1
)
, grouped AS
(
    SELECT n, (SELECT MAX(groupnum) FROM groups
                 WHERE groups.n <= base.n
              ) groupnum
      FROM base
)
SELECT groupnum, MIN(n), MAX(n)
  FROM grouped
  GROUP BY groupnum
  ORDER BY groupnum

相关文章