Sélection de la version la plus récente et spécifique dans chaque groupe d'enregistrements, pour plusieurs groupes
Le problème:
J'ai une table qui enregistre les lignes de données dans foo
. Chaque fois que la ligne est mise à jour, une nouvelle ligne est insérée avec un numéro de révision. Le tableau ressemble à:
id rev field
1 1 test1
2 1 fsdfs
3 1 jfds
1 2 test2
Noter que dans le tableau du dernier enregistrement est une version plus récente de la première ligne.
Personne ne sait d'une manière efficace à la requête pour la version la plus récente des lignes, et une version spécifique d'enregistrements? Par exemple, une requête pour rev=2
serait de retour le 2, 3 et 4 rangs (pas remplacé le 1er rang), alors que les requêtes pour rev=1
les rendements de ces lignes avec rev <= 1 et en cas de duplication de l'ids, l'une avec le plus haut numéro de révision est choisi (record: 1, 2, 3).
Je ne suis pas sûr si cela est encore possible dans SQL Server...
Je préférerais pas de retourner le résultat de façon itérative.
source d'informationauteur orange
Vous devez vous connecter pour publier un commentaire.
Pour obtenir uniquement des dernières révisions:
Pour obtenir une révision spécifique, dans ce cas, 1 (et si un article n'est pas de la révision mais la prochaine plus petite révision):
Il pourrait ne pas être le moyen le plus efficace pour ce faire, mais pour l'instant je ne peut pas la figure d'une meilleure façon de le faire.
C'est comment j'allais le faire.
ROW_NUMBER()
nécessite SQL Server 2005 ou plus tardDes données de l'échantillon:
La requête:
L'intérieur
SELECT
retourne tous les documents pertinents, et à l'intérieur de chaqueid
groupe (c'est lePARTITION BY
), calcule le nombre de ligne au moment de la commande par ordre décroissant d'rev
.L'extérieur
SELECT
juste sélectionne le premier membre (ainsi, l'un avec la plus hauterev
) de chaqueid
groupe.De sortie lors de l'
@desiredRev = 2
:De sortie lors de l'
@desiredRev = 1
:Si vous voulez toutes les dernières révisions de chaque champ, vous pouvez utiliser
Dans le cas de votre exemple, qui serait de retour
Comment à ce sujet?
Pour des requêtes spécifiques de révision révision 1,
Voici une solution alternative a subit une mise à jour des coûts, mais est beaucoup plus efficace pour sélectionner les données les plus récentes lignes qu'il évite le calcul de
MAX(rev)
. Il fonctionne également lorsque vous êtes en train de faire en vrac les mises à jour des ensembles ou sous-ensembles de la table. J'avais besoin de ce modèle pour s'assurer que je efficace pourrait passer à un nouveau jeu de données qui a été mis à jour via une longue mise à jour en bloc, sans aucune des fenêtres de temps où l'on avait été partiellement mise à jour des données visibles.Vieillissement
rev
colonne avec unage
colonneage = 0
age = -1
Dans mon cas, cela a été un lent processus d'exécution long.UPDATE table-name age = age + 1
pour toutes les lignes mises à jour. Cette commute l'affichage de la nouvelle données les plus récentes.age > N
Indexation
age
et puisid
donc, la vue y est agréable et rapide et peut également être utilisé pour la recherche par id. Bien que cette clé est effectivement unique, ses temporairement non-uniques quand vous êtes vieillissement les lignes (en cours deUPDATE SET age=age+1
) de sorte que vous aurez besoin afin de le rendre unique et idéalement l'index cluster. Si vous avez besoin de trouver toutes les versions d'unid
vous aurez besoin d'un index supplémentaire surid
.Enfin ... disons que vous êtes dans un mauvais jour, et le traitement par lots des pauses. Vous pouvez rapidement revenir à une ancienne version du jeu de données en exécutant:
UPDATE table-name SET age = age - 1
-- Restaurer une versionDELETE table-name WHERE age < 0
-- Nettoyer les mauvaises chosesNote: je vous recommande de nommer le nom de la colonne
RowAge
au lieu deage
pour indiquer ce modèle est utilisé car il est plus clair que le son d'une base de données sur la valeur et complète de SQL ServerRowVersion
nom de la colonne et de la convention de nommage. Maintenant, il n'entre pas en conflit avec une colonne ou de la vue qui doit ramener l'âge de la personne.Contrairement à d'autres solutions, ce modèle fonctionne pour les non bases de données SQL Server, par conséquent, moins l'enfermement dans.