Обновить столбец значением из предыдущей строки в зависимости от условий - PullRequest
0 голосов
/ 05 июня 2018

У меня есть таблица, в которой мне нужно найти значение, удовлетворяющее нескольким условиям, и, если эти условия выполняются, мне нужно присвоить одно и то же значение каждому из столбцов

 Table 
  ID       Name   Salary  rownum
  1         Jon    500     1
  1         Jim    600     2 
  1         Jack   700     3
  1         Bob    1000    4
  2         Adam    500    1
  2         Aron    600    2 
  2         James   900    3
  2         Jay     1000   4

Первое условие - мне нужноУ меня такой же идентификатор, тогда внутри идентификатора мне нужно сравнить первую строку со второй, если разница меньше или равна 100. Я могу сравнивать только Rownum 1 с 2 и 2 с 3 и так далее.После определения, удовлетворяется ли условие, мне нужно обновить значения зарплаты до значения, которое существует для Rownum 1, до точки, где условие выполняется, сохраняя имена одинаковыми.

Ожидаемый результат

 Table 
  ID       Name   Salary  rownum
  1         Jon    500     1
  1         Jim    500     2 
  1         Jack   500     3
  1         Bob    1000    4
  2         Adam    500    1
  2         Aron    500    2 
  2         James   900    3  
  2         Jay     900    4                 

Джим имел 600 в качестве зарплаты, а разница с зарплатой Джона <= 100, а у Джека 700 различий с зарплатой Джима <= 100, поскольку Джим находится в пределах зарплаты Джона.и Джек находится в пределах зарплаты Джима, эти значения непрерывны, поэтому нам нужно значение Джона для этих строк, в то время как Боб независим, поскольку он не попадает в диапазон.Та же логика применяется для ID = 2 </p>

Ответы [ 2 ]

0 голосов
/ 05 июня 2018

Ваша проблема не так проста, как кажется, поскольку возможно, что предыдущая строка может иметь большее значение (скажем, 800) по сравнению с текущей строкой (скажем, 750).Также возможно, что островов и щелей больше, чем просто одного.

Ниже мое решение.Также см. рабочая демонстрация

; with cte as 
(
    select *
    , toUpdate= case 
                    when 
                        salary - lag( salary) over( partition by Id order by rownum asc) between 0 and 100 
                    then 
                        1 
                    else 
                        0 
                end
from t
)

update t5 
set t5.salary=t4.newsalary
from t t5 
join
(
    select 
    t1.*, 
    rn=row_number () over( partition by t1.id, t1.rownum order by t3.rownum desc), 
    newsalary=t3.salary 
    from cte t1 
        outer apply
            (
                select *  
                    from cte t2 
                where t2.id=t1.id 
                    and t2.rownum<t1.rownum 
                    and t2.toUpdate=0
              ) t3
    )t4 
on t4.rn=1 and t4.toUpdate=1 and t5.id=t4.id and t5.rownum=t4.rownum

select * from t
0 голосов
/ 05 июня 2018

попробуйте это:

, если «left join self + where Salary + 100 * (jointable.rownum - rownum) = jointable.Salary данные не равны нулю», то обновите Зарплату

update T
set Salary = NewSalary
from (
  select T2.*,T1.Salary NewSalary,(T2.rownum - T1.rownum) fd
  from [Table] T1
  left join [Table] T2 on T1.ID = T2.ID
    and T1.rownum <> T2.rownum
    and (T2.rownum - T1.rownum) > 0 
    and T1.[Salary] + 100 * (T2.rownum - T1.rownum) = T2.[Salary] 
  where T2.id is not null
) T ;  

| ID |  Name | Salary | rownum |
|----|-------|--------|--------|
|  1 |   Jon |    500 |      1 |
|  1 |   Jim |    500 |      2 |
|  1 |  Jack |    500 |      3 |
|  1 |   Bob |   1000 |      4 |
|  2 |  Adam |    500 |      1 |
|  2 |  Aron |    500 |      2 |
|  2 | James |    900 |      3 |
|  2 |   Jay |    900 |      4 |

SQL Fiddle DEMO LINK

...