简体   繁体   中英

Oracle get first value over ordered group

I try many oracle analytic functions to achieve my needs but could not made it. here is a simple example:

WITH W1 AS (
SELECT 100 key1, 0 key2, 0 key3, 'open'  status, 'date1' date_column FROM DUAL UNION ALL
SELECT 100 key1, 0 key2, 1 key3, 'open'  status, 'date2' date_column FROM DUAL UNION ALL
SELECT 100 key1, 0 key2, 2 key3, 'close' status, 'date3' date_column FROM DUAL UNION ALL
SELECT 100 key1, 0 key2, 3 key3, 'close' status, 'date4' date_column FROM DUAL UNION ALL
SELECT 100 key1, 0 key2, 4 key3, 'close' status, 'date5' date_column FROM DUAL UNION ALL
SELECT 100 key1, 0 key2, 5 key3, 'open'  status, 'date6' date_column FROM DUAL UNION ALL
SELECT 100 key1, 0 key2, 6 key3, 'open'  status, 'date7' date_column FROM DUAL )
SELECT W1.*, 
       CASE WHEN LAG(status,1) OVER(PARTITION BY key1,key2 ORDER BY key3) <> status THEN date_column
            ELSE FIRST_VALUE(date_column) OVER (PARTITION BY key1,key2,status ORDER BY key3 RANGE BETWEEN UNBOUNDED PRECEDING AND UNBOUNDED FOLLOWING ) END as DESIRED
  FROM W1
 ORDER BY 1,2,3

I am trying get first value over ordered group when status changed. I only need that last row on DESIRED column should be "date6"

Do you have any suggestions ? Oracle 11gr2

Thanks.

Starting from Oracle 12c R1 (12.1), there is a row limiting clause

you can use FETCH FIRST 1 ROWS ONLY;

   WITH W1 AS (
    SELECT 100 key1, 0 key2, 0 key3, 'open'  status, 'date1' date_column FROM DUAL UNION ALL
    SELECT 100 key1, 0 key2, 1 key3, 'open'  status, 'date2' date_column FROM DUAL UNION ALL
    SELECT 100 key1, 0 key2, 2 key3, 'close' status, 'date3' date_column FROM DUAL UNION ALL
    SELECT 100 key1, 0 key2, 3 key3, 'close' status, 'date4' date_column FROM DUAL UNION ALL
    SELECT 100 key1, 0 key2, 4 key3, 'close' status, 'date5' date_column FROM DUAL UNION ALL
    SELECT 100 key1, 0 key2, 5 key3, 'open'  status, 'date6' date_column FROM DUAL UNION ALL
    SELECT 100 key1, 0 key2, 6 key3, 'open'  status, 'date7' date_column FROM DUAL )
    SELECT W1.*, 
           CASE WHEN LAG(status,1) OVER(PARTITION BY key1,key2 ORDER BY key3) <> status THEN date_column
                ELSE FIRST_VALUE(date_column) OVER (PARTITION BY key1,key2,status ORDER BY key3 RANGE BETWEEN UNBOUNDED PRECEDING AND UNBOUNDED FOLLOWING ) END as DESIRED
      FROM W1
     ORDER BY 1,2,3
     FETCH FIRST 1 ROWS ONLY;

see this for doc https://oracle-base.com/articles/12c/row-limiting-clause-for-top-n-queries-12cr1

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM