如何查询非连续值?

时间:2019-07-07 10:22:06

标签: sql oracle

我在名为id的表中有1, 3, 4, 9, 10, 11列:t_mark

如何获得非连续范围? (例如[1, 3][4, 9]

3 个答案:

答案 0 :(得分:3)

或者,使用LEAD分析函数以及您的花式格式。 TEST CTE是您已经拥有的;从第9行开始就是您所需要的。

SQL> with test (col) as
  2    (select 1  from dual union all
  3     select 3  from dual union all
  4     select 4  from dual union all
  5     select 9  from dual union all
  6     select 10 from dual union all
  7     select 11 from dual
  8    ),
  9  temp as
 10    (select col,
 11            lead(col) over (order by col) lcol
 12     from test
 13    )
 14  select '[' || col ||' - '|| lcol ||']' result
 15  From temp
 16  where lcol - col > 1
 17  order by col;

RESULT
-------------------------------------------------------
[1 - 3]
[4 - 9]

SQL>

[编辑:调整后,您不必考虑太多]

这是您拥有的:

SQL> select * From t_mark;

      M_ID
----------
         1
         3
         4
         9
        10
        11

6 rows selected.

这就是您需要的:

SQL> with temp as
  2    (select m_id,
  3            lead(m_id) over (order by m_id) lm_id
  4     from t_mark
  5    )
  6  select '[' || m_id ||' - '|| lm_id ||']' result
  7  From temp
  8  where lm_id - m_id > 1
  9  order by m_id;

RESULT
------------------------------------------------------------------
[1 - 3]
[4 - 9]

SQL>

基本上,您应该学习如何使用CTE(通用表表达式,也称为 with factoring子句)。

答案 1 :(得分:1)

假设“列表”是指带有一列的表,那么您可以使用lag()来做到这一点:

select prev_number, number
from (select t.*, lag(number) over (order by number) as prev_number
      from t
     ) t
where prev_number <> number - 1;

答案 2 :(得分:0)

这应该可以解决问题:

WITH original_table(number_column) as (select 1  from dual union all
                                       select 3  from dual union all
                                       select 4  from dual union all
                                       select 9  from dual union all
                                       select 10 from dual union all
                                       select 11 from dual),
numbers AS (
    SELECT row_number() over (ORDER BY number_column ASC ) row_num,
           number_column
    FROM original_table
)

SELECT nb1.number_column AS lnumber,
       nb2.number_column AS rnumber

FROM numbers nb1

  INNER JOIN numbers nb2 ON nb1.row_num + 1 = nb2.row_num 
                        AND nb1.number_column + 1 < nb2.number_column

结果:

| LNUMBER | RNUMBER |
|---------|---------|
| 1       | 3       |
| 4       | 9       |

Link to the dbfiddle for testing