代码之家  ›  专栏  ›  技术社区  ›  Avi

根据条件用前一行的值更新列

  •  2
  • Avi  · 技术社区  · 7 年前

    我有一个表,我需要找到一个满足几个条件的值,如果满足这些条件,我需要为每个列分配相同的值

     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
    

    第一个条件是我需要有相同的id,然后在id内,如果差异小于或等于100,我需要比较第一行和第二行。我只能比较rownum 1和2,以及rownum 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英镑,因为吉姆在乔恩的工资范围内,而杰克在吉姆的工资范围内,这些值是连续的,所以我们需要这些行的乔恩的价值,而鲍勃是独立的,因为它不属于T。他射程。相同的逻辑适用于id=2

    2 回复  |  直到 7 年前
        1
  •  1
  •   DhruvJoshi    7 年前

    您的问题并不像看起来那么简单,因为前一行可能比当前行(比如750)具有更大的值(比如800)。 也有可能有更多的岛屿和差距,而不仅仅是一个。

    下面是我的解决方案。也看到 working demo

    ; 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
    
        2
  •  3
  •   Wei Lin    7 年前

    试试这个:

    如果 “ 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