【问题标题】:Update multiple rows based on an ordered array基于有序数组更新多行
【发布时间】:2020-07-21 12:45:06
【问题描述】:

我有一个表格,它有一个位置 pos 列来指示项目应在 UI 中显示的顺序:

|               list_has_task              |
|------------------------------------------|
| list_id (fk) | task_id (fk) | pos | meta |
| ------------ | ------------ | --- | ---- |
|         6969 |         1001 |  1  | abcd |
|         6969 |         1002 |  2  | efgh |
|         6969 |         1003 |  3  | ijkl |
|         6969 |         1004 |  4  | mnop |
|         6969 |         1005 |  5  | qrst |
                     (...)

当用户重新排列列表时,我会得到一个有序的 ID 列表作为数组:

(1004,1003,1002,1005,1001)

我想将这些行更新为该顺序。
这是我所拥有的:

BEGIN;
   UPDATE list_has_task SET pos = 1 WHERE list_id = 6969 AND task_id = 1004;
   UPDATE list_has_task SET pos = 2 WHERE list_id = 6969 AND task_id = 1003;
   UPDATE list_has_task SET pos = 3 WHERE list_id = 6969 AND task_id = 1002;
   UPDATE list_has_task SET pos = 4 WHERE list_id = 6969 AND task_id = 1005;
   UPDATE list_has_task SET pos = 5 WHERE list_id = 6969 AND task_id = 1001;
COMMIT;

有没有更好的方法?

【问题讨论】:

    标签: sql arrays postgresql sql-update


    【解决方案1】:

    您可以将多表 UPDATEVALUES 表一起使用:

    UPDATE list_has_task AS l
    SET pos = a.pos
    FROM (VALUES (1, 1004), (2, 1003), (3, 1002), (4, 1005), (5, 1001)) AS a(pos, task_id)
    WHERE l.task_id = a.task_id
    

    输出:

    list_id     task_id     pos     meta
    6969        1004        1       mnop
    6969        1003        2       ijkl
    6969        1002        3       efgh
    6969        1005        4       qrst
    6969        1001        5       abcd
    

    Demo on SQLFiddle

    【讨论】:

    • 这正是我需要的!
    • 我也不知道 SQLFiddle 的存在! tysm
    • @Vitim.us 是的,SQLFiddle 很好(我喜欢它的文本到 ddl 功能),但也有 dbfiddle.uk 有更大范围的可用 DBMS 和 db-fiddle.com 也有文本到ddl
    【解决方案2】:

    我得到一个有序的 ID 列表作为一个数组。

    您可以直接使用unnest() 并利用WITH ORDINALITY 功能:

    UPDATE list_has_task l
    SET    pos = x.ord
    FROM   unnest('{1004,1003,1002,1005,1001}'::int[]) WITH ORDINALITY x(task_id, ord)
    WHERE  l.list_id = 6969
    AND    l.task_id = x.task_id;
    

    db小提琴here

    见:

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2021-03-15
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2014-10-28
      • 2022-01-07
      相关资源
      最近更新 更多