【问题标题】:PostgreSQL UPDATE with case and subquery to get value from row right abovePostgreSQL UPDATE 与案例和子查询从上面的行中获取值
【发布时间】:2018-11-02 11:40:23
【问题描述】:

考虑下表:

+-------+-----+----+
| 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 |
+-------+-----+----+ 

非常感谢您的任何建议!

【问题讨论】:

    标签: sql postgresql sql-update subquery case


    【解决方案1】:

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

    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');
    

    【讨论】:

    • 非常感谢! id 中没有间隙。这非常接近但不太有效。我不知道为什么,但更新后的行现在是上一行带有 RP 和 RB 的行,而不是下一行带有 RV 的行...您看到错误了吗?
    • @mr.parchman 。 . .我想我误解了这个问题。你的问题只有两行。我将其解释为指的是三行。
    • 是的,完全正确..只有两行..一个以 RP 或 RB 作为流派,下一行以 RV 作为流派
    猜你喜欢
    • 1970-01-01
    • 2015-10-10
    • 1970-01-01
    • 2015-11-09
    • 1970-01-01
    • 2014-06-11
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多