web-dev-qa-db-fra.com

Trier les lignes de table et enregistrer les numéros de ligne à l'aide de la mise à jour

J'ai Postgres 9.5 avec une table movimientos qui possède les données suivantes:

| 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 |

Et j'ai besoin de numéroter les enregistrements en fonction du champ orden et de conserver ces numéros dans le champ numero, car j'ai besoin de ces données pour trier et rechercher par numero dans les rapports. Exemple:

| 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 |

J'ai essayé de le faire en utilisant une fonction avec un FOR mais est très lent avec un million de lignes.

Comment faire cela en utilisant un simple UPDATE?

5
Aegis

Joignez-vous à une sous-requête qui calcule numero avec la Fonction de fenêtre 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;

Détails pour UPDATE syntaxe dans le manuel .

Si vous avez un accès en écriture simultanée, vous devez verrouiller la table pour éviter les conditions de course.

Notez que la mise à jour chaque Rangée dans une table est coûteuse de toute façon. La table augmente généralement à deux fois sa taille et VACUUM ou VACUUM FULL peut être en ordre.

En fonction de votre situation complète, elle Mai Soyez plus efficace pour écrire une nouvelle table pour commencer. Réponses connexes avec instructions:

Je ne suis pas convaincu que vous avez besoin de la colonne numero dans votre table du tout. Peut-être que vous recherchez un (MATERIALIZED VIEW . Réponciation Réponse Répondre sur SO:

5