Найти следующее наименьшее значение по разделу - PullRequest
1 голос
/ 11 июля 2019

Я ищу однострочную оконную функцию, чтобы получить следующее наименьшее значение Field2 над разделом Field1 без подзапроса.

Field1   Field2      Last_Val
A         1          Null
A         2          1
A         2          1
A         2          1
A         3          2
B         1          Null
B         7          1

Я знаю, как это сделать несколькими способами, проще всего быть

  SELECT T1.Field1,
         T1.Field2,
         ( SELECT MAX(T2.Field2)
             FROM TEST_DATA T2
            WHERE T1.Field1 = T2.Field1
              AND T1.Field2 > T2.Field2
         ) last_val
    FROM TEST_DATA T1;

Но мне интересно, можно ли это сделать одним предложением.

Ответы [ 2 ]

2 голосов
/ 11 июля 2019

Вам нужна оконная аналитическая функция с предложением RANGE:

Установка Oracle :

CREATE TABLE table_name ( Field1, Field2 ) AS
SELECT 'A', 1 FROM DUAL UNION ALL
SELECT 'A', 2 FROM DUAL UNION ALL
SELECT 'A', 2 FROM DUAL UNION ALL
SELECT 'A', 2 FROM DUAL UNION ALL
SELECT 'A', 3 FROM DUAL UNION ALL
SELECT 'B', 1 FROM DUAL UNION ALL
SELECT 'B', 7 FROM DUAL

Запрос :

select field1,
       field2,
       max(field2) over(
         partition by field1
         order by field2
         range between unbounded preceding and 1 preceding
       ) as last_val
from   table_name

Выход :

FIELD1 | FIELD2 | LAST_VAL
:----- | -----: | -------:
A      |      1 |     <em>null</em>
A      |      2 |        1
A      |      2 |        1
A      |      2 |        1
A      |      3 |        2
B      |      1 |     <em>null</em>
B      |      7 |        1

db <> скрипка здесь

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

Если ваши значения целые, то это работает:

with t as (
      select 'A' as field1, 1 as field2 from dual union all
      select 'A', 2 from dual union all
      select 'A', 2 from dual union all
      select 'A', 2 from dual union all
      select 'A', 3 from dual
     )
select t.*,
        max(field2) over (partition by field1 order by field2 range between unbounded preceding and 1 preceding)
from t;
...