在列 return 中重新排序(重新排序) false

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 与相等运算符 = 进行比较,得到 boolean false .当与 concat() 连接时,它被强制转换为文本 'false'.

实际的变量赋值见:

  • Store query result in a variable using in PL/pgSQL

但这不是您需要的。有多种分配序号的方法。

您可以使用(临时)SEQUENCE 来完成任务:

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

参见:

  • Implementing a total order ranking in PostgreSQL 8.3

要在 table 列中获取序列号(任意顺序),我只需:

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

如果您不想要任意排序顺序,则必须 ORDER BY 一些东西。喜欢 ORDER BY id。使用(标准 SQL)window function row_number() to generate the sequence. In a (non-standard) FROM clause to the 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<>fiddle here

参见:

  • Update a column of a table with a column of another table in PostgreSQL

但是,严重的是,您不想使用 reserved word order 作为标识符。那是自找麻烦