在分区上查找下一个最小值

时间:2019-07-11 15:32:10

标签: sql oracle oracle12c

我正在寻找一种单线窗口函数,以在没有子查询的情况下在Field1的分区上获得Field2的下一个最小值。

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 个答案:

答案 0 :(得分:2)

您需要一个带有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 |     null
A      |      2 |        1
A      |      2 |        1
A      |      2 |        1
A      |      3 |        2
B      |      1 |     null
B      |      7 |        1

db <>提琴here

答案 1 :(得分:1)

如果您的值是整数,则可以这样做:

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;