2009-09-16 6 views
1

J'ai des structures de table qui incluent une clé primaire composite de l'ID & révision où les deux sont des entiers.Sélectionnez la dernière révision de chaque ligne dans une table

J'ai besoin d'une requête qui retournera la dernière révision de chaque ligne. Si j'ai bien compris this answer alors ce qui suit aurait travaillé sur une base de données Oracle. J'utilise SQL Server (2005) et j'ai besoin d'une requête performante pour faire la même chose.

Répondre

2

Voir this posté par ayende pour une ealuation des meilleures stratégies.

+0

+1 Merci pour cela. Très utile en effet. – grenade

1

Je voudrais essayer de créer une sous-requête comme ceci:

SELECT Id, Titre de Task T, (Select, Max (révision) MaxRev du groupe de travail par ID) LatestT OÙ T.Revision = LatestT. MaxRev et T.ID = LatestT.ID

Une autre option consiste à "tricher" et créer un déclencheur qui marquera la révision comme dernière révision si un élément est ajouté. Puis ajoutez ce champ à l'index. (Je lier la table à insérer uniquement)

également un index sur ID, révision desc pourrait aider à la performance

+0

+1 Cheers !, fonctionne quand j'ajoute le désambiguïsant et semble être la même solution que celle de Maximilian. J'aime aussi votre idée de tricherie et je finirai probablement avec une variation de celle basée sur le post lié par Johannes Rudolph. – grenade

+0

Np ... Tout dépend de l'utilisation de la table etc ... Assurez-vous également que vous construisez l'index de couverture avec les 2 champs asgested (Tri inversé du 2ème champ). –

+0

attention à l'aide de "vieux style" rejoint –

1

Je pense que cela devrait fonctionner (je ne l'ai pas le tester) ...

SELECT  ID, 
      Title 
FROM  Task AS T 
INNER JOIN 
(
    SELECT   ID, 
        Max(Revision) 
    FROM   Task 
    GROUP BY  ID 
) AS sub 
ON   T.ID = sub.ID 
AND   T.Revision = sub.Revision 
+0

Il a presque fonctionné. J'ai ajouté un désambiguïsateur entre le premier "SELECT" et "ID" [par exemple: "SELECT T.ID"] et un nom de colonne après "Max (Revision)" [par exemple: "Max (Revision) Revision"]. et cela renvoie les lignes correctes. Avoir encore à l'essai de performance ... – grenade

0

La requête que vous avez affichée fonctionnera dans SQL 2005 (en mode de compatibilité 90) avec les erreurs de syntaxe corrigée:

SELECT t1.Id, t1.Title 
FROM (SELECT Id, Revision, MAX(Revision) OVER (PARTITION BY Id) LatestRevision FROM Task) AS x 
JOIN Task as t1 
ON t1.Revision = x.LatestRevision 
AND t1.id  = x.id 
+1

Merci. Votre révision renvoie les bonnes lignes mais crée des résultats en double. Je n'ai pas compris pourquoi. – grenade

0

essayez ceci:

DECLARE @YourTable table(RowID int, Revision int, Title varchar(10)) 
INSERT INTO @YourTable VALUES (1,1,'A') 
INSERT INTO @YourTable VALUES (2,1,'B') 
INSERT INTO @YourTable VALUES (2,2,'BB') 
INSERT INTO @YourTable VALUES (3,1,'C') 
INSERT INTO @YourTable VALUES (4,1,'D') 
INSERT INTO @YourTable VALUES (1,2,'AA') 
INSERT INTO @YourTable VALUES (2,3,'BBB') 
INSERT INTO @YourTable VALUES (5,1,'E') 
INSERT INTO @YourTable VALUES (5,2,'EE') 
INSERT INTO @YourTable VALUES (4,2,'DD') 
INSERT INTO @YourTable VALUES (4,3,'DDD') 
INSERT INTO @YourTable VALUES (6,1,'F') 

;WITH YourTableRank AS 
(
SELECT 
    RowID,Revision,Title, ROW_NUMBER() OVER(PARTITION BY RowID ORDER BY RowID,Revision DESC) AS Rank 
    FROM @YourTable 
) 
SELECT 
    RowID, Revision, Title 
    FROM YourTableRank 
    WHERE Rank=1 

SORTIE:

RowID  Revision Title 
----------- ----------- ---------- 
1   2   AA 
2   3   BBB 
3   1   C 
4   3   DDD 
5   2   EE 
6   1   F 

(6 row(s) affected) 
Questions connexes