使用 UPDATE 对表行进行排序并保存行号

Aeg*_*gis 5 postgresql performance window-functions update query-performance

我的 Postgres 9.5 有一个movimientos包含以下数据的表:

| id | concepto | movimiento | numero | orden |
|  1 | AJUSTE 1 |       2542 |      0 |     2 |
|  2 | APERTURA |      12541 |      0 |     1 |
|  3 | AJUSTE 2 |       2642 |      0 |     2 |
|  4 | CIERRE   |      22642 |      0 |     3 |
Run Code Online (Sandbox Code Playgroud)

我需要根据orden字段对记录进行编号并将这些数字保留在numero字段中,因为我需要这些数据numero在报告中进行排序和搜索。例子:

| id | concepto | movimiento | numero | orden |
|  2 | APERTURA |      12541 |      1 |     1 |
|  1 | AJUSTE 1 |       2542 |      2 |     2 |
|  3 | AJUSTE 2 |       2642 |      3 |     2 |
|  4 | CIERRE   |      22642 |      4 |     3 |
Run Code Online (Sandbox Code Playgroud)

我尝试使用带有 a 的函数来做到这一点,FOR但有一百万行的速度非常慢。

如何使用简单的方法做到这一点UPDATE

Erw*_*ter 6

加入numero使用窗口函数row_number()计算的子查询:

UPDATE movimientos m
SET    numero = sub.rn
FROM  (SELECT id, row_number() OVER (ORDER BY orden, id) AS rn FROM movimientos) sub
WHERE  m.id = sub.id;
Run Code Online (Sandbox Code Playgroud)

UPDATE手册中语法的详细信息。

如果您具有并发写访问权限,则需要锁定表以避免竞争条件。

请注意,无论哪种方式,更新表中的每一行都是昂贵的。该表通常会增长到其大小的两倍,并且VACUUMVACUUM FULL可能是有序的。

根据您的完整情况,开始时编写新表可能更有效。带说明的相关答案:

但是,我不相信您根本不需要numero的列。也许您正在寻找一个MATERIALIZED VIEW. 最近关于 SO 的相关回答: