Как запросить непоследовательные значения? - PullRequest
0 голосов
/ 07 июля 2019

У меня есть столбец id: 1, 3, 4, 9, 10, 11 в таблице с именем t_mark

Как я могу получить непоследовательный диапазон? (например, [1, 3], [4, 9])

Ответы [ 3 ]

3 голосов
/ 07 июля 2019

В качестве альтернативы можно использовать аналитическую функцию LEAD и форматирование fancy .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 (общее табличное выражение, то есть спункт факторинга ).

1 голос
/ 07 июля 2019

Предполагая, что под "списком" вы подразумеваете таблицу со столбцом, вы можете сделать это с помощью 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;
0 голосов
/ 07 июля 2019

Это должно сработать:

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       |

Ссылка на dbfiddle для тестирования

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...