Resequence (reorder) in column return false



基于mysql:

SET @ordering_inc = 1;
SET @new_ordering = 0;
UPDATE tasks
SET order = CONCAT("p/", @new_ordering := @new_ordering + @ordering_inc));

结果:

id | order
21 | p/1
32 | p/2
53 | p/3

但是在Postgresql中不工作

DO $$
DECLARE
ordering_inc integer := 1;
new_ordering integer := 0;
BEGIN
UPDATE tasks
SET order = CONCAT('p/', new_ordering = new_ordering + ordering_inc);
END $$;

结果:

id | order
21 | p/false
32 | p/false
53 | p/false

我做错了什么?

注意:我尝试在查询中使用:=,但给出语法错误

在MySQL中,表达式@new_ordering := @new_ordering + @ordering_inc赋值给变量

另一方面,Postgres对表达式求值new_ordering = new_ordering + ordering_inc根据标准SQL:用相等运算符=new_orderingnew_ordering + ordering_inc进行比较,得到booleanfalse。当与concat()连接时,它被强制输入'false'。

实际的变量赋值见:

  • 将查询结果存储在PL/pgSQL中使用的变量

但这不是你在这里需要的。有多种方法来分配序号。

您可以为任务使用(临时)SEQUENCE:

CREATE TEMP SEQUENCE foo_seq;
UPDATE tasks
SET    "order" = 'p/' || nextval('foo_seq');

:

  • 在PostgreSQL 8.3
  • 中实现总排序

要获取表列中的序列号(任意顺序),只需:

ALTER TABLE tasks
DROP COLUMN "order"
, ADD COLUMN  "order" serial;

如果你不想要一个任意的排序顺序,你必须ORDER BY一些东西。喜欢ORDER BY id。使用(标准SQL)窗口函数row_number()生成序列。在一个(非标准的)FROM子句到UPDATE:

UPDATE tasks t
SET    "order" = t1.rn
FROM  (SELECT id, row_number() OVER (ORDER BY id)  AS rn FROM tasks) t1
WHERE  t.id = t1.id;

db<此处小提琴>

:

  • 用一个表的列更新另一个表的列

但是,说真的,您不会希望使用保留字order作为标识符。那是自找麻烦。

最新更新