如何比较旧行和上一行并仅使用Lag在sql中获取更改的数据

时间:2016-10-07 17:24:37

标签: sql oracle oracle-sqldeveloper

我有一个结构为xx_asg的表:

person_id  grade_id effective_start_date effective_end_date
1            null       28-Jan-97             28-Jan-16
1            35         29-Jan-16             31-Dec-4712
6            35         12-Jun-93             31-Jul-93
6            35         01-Aug-93             30-Sep-99

我必须通过比较前一行和下一行来查明grade_id是否有任何变化。 如果有变化,那么我必须获取标志为'Y'的新列 还有新等级的effective_start_date。我试图创建以下查询:

SELECT  *
From    (
        Select  Person_id,
   Grade_Id,
                LAG(grade_id) OVER (PARTITION BY person_ID ORDER BY effective_start_Date) AS prev_grade_line1,
                Row_Number() Over (Partition By Person_Id Order By Effective_Start_Date Desc) As Rn,
                Effective_Start_Date
                        From    xx_asg
  --WHERE   person_ID = 3
        )
Where   Rn = 1
order by person_id

;

但是这个查询也将prev_grade_line1和新的成绩id返回为null或相同:

enter image description here

Output should look like :

person_id  grade_id prev_grade_id effective_start_date Flag
1            null       35             29-Jan-97        Y         
6            35         35             NULL             NULL


OR 

ONLY CHAGED ROW 
person_id  grade_id prev_grade_id effective_start_date Flag
1            null       35             29-Jan-97        Y    

使用时:

enter image description here

此查询也返回第一行。那就是它将第一行的前一个ggrade视为null。实际上只有3个变化,但这个查询返回了四个字符

enter image description here

1 个答案:

答案 0 :(得分:1)

使用where条件仅在获取上一行的值后获取所需的行。

select t.*, 'Y' flag
from (
select  
Person_id,
Grade_Id,
LAG(grade_id) OVER(PARTITION BY person_ID ORDER BY effective_start_Date) prev_grade_line1,
Effective_Start_Date,
row_Number() Over(Partition By Person_Id Order By Effective_Start_Date) As rn
from xx_asg
) t
where nvl(grade_id,10000000) <> nvl(prev_grade_line1,10000000) 
and rn > 1