用于在组内创建升序值的 SQL 查询

标签 sql postgresql sql-update

我有下表:

+----+--------+-----+
| id | fk_did | pos |
+----+--------+-----+

此表包含数百行,每一行都使用 fk_did 引用另一个表。 pos 中的值当前始终为零,我想更改它。

基本上,对于每组 fk_didpos 列应该从零开始并按升序排列。行的排序方式无关紧要。

我想要获得的示例输出(select * from table order by fk_did, pos):

+----+--------+-----+
| id | fk_did | pos |
+----+--------+-----+
| xx |      0 |   0 |
| xx |      0 |   1 |
| xx |      0 |   2 |
| xx |      1 |   0 |
| xx |      1 |   1 |
| xx |      1 |   2 |
| xx |      4 |   0 |
| xx |      8 |   0 |
| xx |      8 |   1 |
| xx |      8 |   2 |
+----+--------+-----+
  • 不得有两行具有相同的 fk_didpos 组合
  • pos 对于每个 fk_did
  • 必须升序
  • 如果有一行 pos > 0,则还必须有一行具有相同的 fk_did 和较低的 pos

这可以通过单个更新查询完成吗?

最佳答案

您可以使用窗口函数执行此操作:

update the_table
   set pos = t.rn - 1
from (
   select id, 
          row_number() over (partition by fk_id) as rn
   from the_table
) t
where t.id = the_table.id;

pos 的顺序将或多或少是随机的,因为没有 order by,但你说过这无关紧要。

这假设 id 是唯一的,如果不是,您可以使用内部列 ctid 代替。

关于用于在组内创建升序值的 SQL 查询,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/35384035/

相关文章:

javascript - Node.JS + MySQL - 将 40 多个 UPDATE 语句压缩成一个,每个语句都有唯一的 WHERE 子句

Mysql 行总和作为行值

sql - MySQL:选择剩余行

mysql - 减少sql中的重复项

postgresql - 在 psql 中定义多行字符串

mysql 工作台不能 : update where like

mysql - 正确使用连接表?

php - PostgreSQL 数据库似乎不适用于 GeoServer

sql - 提高 Postgres 中的子查询性能

c# - MySQL 查询中输入字符串的格式不正确错误