PostgreSQL带有大小写和子查询的UPDATE,可从上方的行中获取值

时间:2018-11-02 11:40:23

标签: sql postgresql sql-update subquery case

考虑下表:

+-------+-----+----+
| genre | ref | id |
+-------+-----+----+
| CIT   | 000 |  1 |
| RP    | 111 |  2 |
| RV    |     |  3 |
| RP    | 777 |  4 |
| HY    |     |  5 |
| RB    | 222 |  6 |
| RV    |     |  7 |
+-------+-----+----+ 

我正在寻找一条UPDATE语句,该语句将检查类型为'RP'或'RB'的行之后的行是否为类型为'RV'的行,如果是,则应使用以下值更新它上方的行(始终在上方;“ id-1”)。因此,在此测试用例中,它将如下所示:

+-------+-----+----+
| genre | ref | id |
+-------+-----+----+
| CIT   | 000 |  1 |
| RP    | 111 |  2 |
| RV    | 111 |  3 |
| RP    | 777 |  4 |
| HY    |     |  5 |
| RB    | 222 |  6 |
| RV    | 222 |  7 |
+-------+-----+----+ 

非常感谢您的任何建议!

1 个答案:

答案 0 :(得分:0)

我的第一个想法是使用窗口函数:

update t
    ref = tt.ref
from (select t.*,
             lag(ref) over (order by id) as prev_ref
      from t
     ) tt
where tt.id = t.id and
      t.genre = 'RV' and
      t.prev_genre in ('RP', 'RB');

如果您碰巧知道id之间没有空格,那么可以使用联接:

update t
    set t.ref = tprev.ref
from t tprev cross join
     t tnext
where tprev.id = t.id - 1 
      t.genre = 'RV' and
      tprev.genre in ('RP', 'RB');