基于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_ordering
比较 new_ordering + ordering_inc
与 =
,生成 boolean
false
。当与 concat()
连接时,它被强制为文本“false”。
实际的变量赋值请参见:
但这不是您需要的。有多种方法可以分配连续编号。
您可以使用(临时)
SEQUENCE
来完成任务:
CREATE TEMP SEQUENCE foo_seq;
UPDATE tasks
SET "order" = 'p/' || nextval('foo_seq');
参见:
要在表列中获取序列号(任意顺序),我只需:
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;
参见:
但是您不想使用 保留字
order
作为标识符。这是自找麻烦。