#sql #oracle #oracle-sqldeveloper
#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 и новый идентификатор класса как нулевой или тот же :
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
При использовании :
Этот запрос также возвращает первую строку. То есть он обрабатывает предыдущий ggrade первой строки как null. В реальном времени есть только 3 изменения, но этот запрос возвращает четыре изменения
Комментарии:
1. как должен выглядеть результат?
2. Спасибо за вопрос. Я обновил его.
Ответ №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
Комментарии:
1. существует вероятность того, что предыдущая оценка равна нулю, а затем значение изменяется в следующей строке, верно? будет ли это работать в этом состоянии
2. см. Редактирование. это также будет обрабатывать значения null .. однако убедитесь, что значение, используемое в
nvl
, является значением, которого нет в столбце grade .null
в текущей строке иnull
в предыдущей строке будут рассматриваться как без изменений.3. Это также не работает.. я обновляю свой ответ скриншотом, чтобы показать вам результат
4. Спасибо @vkp. Затем отображается дополнительный последний столбец. Как и в последней строке: для идентификатора человека 8 grade_id как 24 и previous_grade_id как null
5. я изменил
row number
расчет. ранее это было заказано effective_start_date desc . вы это заметили? попробуйте последнюю версию.