关于相关行组的Oracle LAG

时间:2017-01-18 14:54:57

标签: sql oracle window-functions

鉴于此数据:

LINE DATE
1   08/19/2016
2   08/19/2016
3   08/19/2016
1   07/29/2016
2   07/29/2016
1   06/24/2012
2   06/24/2012
3   06/24/2012

我想生成:

LINE DATE PRIOR_DATE
1   08/19/2016  07/29/2016
2   08/19/2016  07/29/2016
3   08/19/2016  07/29/2016
1   07/29/2016  06/24/2016
2   07/29/2016  06/24/2016
1   06/24/2012  <NULL>
2   06/24/2012  <NULL>
3   06/24/2012  <NULL>

此查询:

SELECT line, date,LAG(date, 1) OVER (partition by date ORDER BY date) AS prior_date ...

生成:

1   08/19/2016  
2   08/19/2016  08/19/2016
3   08/19/2016  08/19/2016
1   07/29/2016  
2   07/29/2016  07/29/2016
1   06/24/2012  
2   06/24/2012  06/24/2012
3   06/24/2012  06/24/2012

我错过了什么?

1 个答案:

答案 0 :(得分:2)

根据您实际执行的结果,可能需要LAST_VALUE()或LAG()。

我在这里给出了两个,所以你可以看到差异:

WITH sample_data AS (SELECT 1 line, to_date('08/19/2016', 'mm/dd/yyyy') dt FROM dual UNION ALL
                     SELECT 2 line, to_date('08/19/2016', 'mm/dd/yyyy') dt FROM dual UNION ALL
                     SELECT 3 line, to_date('08/19/2016', 'mm/dd/yyyy') dt FROM dual UNION ALL
                     SELECT 1 line, to_date('07/29/2016', 'mm/dd/yyyy') dt FROM dual UNION ALL
                     SELECT 2 line, to_date('07/29/2016', 'mm/dd/yyyy') dt FROM dual UNION ALL
                     SELECT 1 line, to_date('06/24/2012', 'mm/dd/yyyy') dt FROM dual UNION ALL
                     SELECT 2 line, to_date('06/24/2012', 'mm/dd/yyyy') dt FROM dual UNION ALL
                     SELECT 3 line, to_date('06/24/2012', 'mm/dd/yyyy') dt FROM dual)
-- end of mimicking a table with data in it
SELECT line,
       dt,
       last_value(dt) OVER (ORDER BY dt RANGE BETWEEN UNBOUNDED PRECEDING AND 1 PRECEDING) prior_dt1,
       LAG(dt) OVER (PARTITION BY line ORDER BY dt) prior_dt2
FROM   sample_data
ORDER BY dt DESC, line;

      LINE DT          PRIOR_DT1   PRIOR_DT2
---------- ----------- ----------- -----------
         1 19/08/2016  29/07/2016  29/07/2016
         2 19/08/2016  29/07/2016  29/07/2016
         3 19/08/2016  29/07/2016  24/06/2012
         1 29/07/2016  24/06/2012  24/06/2012
         2 29/07/2016  24/06/2012  24/06/2012
         1 24/06/2012              
         2 24/06/2012              
         3 24/06/2012