2011-12-15 2 views
1

Je rencontre des problèmes pour extraire les dernières données.Obtention des dernières données de SQL

J'ai une table avec ces données:

ItemId, ShipmentId, Date 

Les articles peuvent être expédiés à plusieurs reprises et une cargaison peuvent contenir plusieurs éléments. J'ai besoin d'obtenir la dernière expédition pour chaque article.

Table ressemble à ceci:

11 12 2011-05-13 
11 2 2011-07-01 
12 2 2000-03-02 
... 

Le résultat devrait être

11 2 2011-07-01 
12 2 2000-03-02 

Je ne peux pas trouver une solution à exclusive. Comment puis-je obtenir la dernière expédition pour chaque article?

+1

Quel est le moteur de base de données? –

+0

Merci pour tout votre message Damien_The_Unbeliever a eu la solution pour moi! – dare2k

Répondre

2

En supposant que vous travaillez avec un moteur de base de données qui prend en charge les fonctions de classement, utilisez un CTE ou sous-requête pour commander les résultats:

;With OrderedItems as (
    select ItemId,ShipmentId,Date, 
     ROW_NUMBER() OVER (PARTITION BY ItemId ORDER By Date desc) as rn 
    from ItemsTable 
) 
select * from OrderedItems where rn = 1 
+0

Merci! Tu es un sauveur! – dare2k

1
select t1.ItemId, t1.ShipmentId, t1.Date 
from tab t1 
join (
    select ItemId, max(Date) as Date 
    from tab 
    group by ItemId 
) t on t1.ItemId = t.ItemId and t1.Date = t.Date 
+0

Cela ne sélectionnera pas l'ID d'expédition qui appartient à la dernière date d'expédition. –

+0

Si j'essaie votre solution, j'obtiens une erreur: Column 'ShipID' est invalide dans la liste de sélection parce qu'il n'est pas contenu dans une fonction d'agrégat ou la clause GROUP BY. – dare2k

+0

@a_horse_with_no_name: vous avez raison, corrigé. –

0

n'a pas testé, mais cette idée générale devrait travailler :

SELECT * FROM YOUR_TABLE T1 
WHERE 
    NOT EXISTS (
     SELECT * FROM YOUR_TABLE T2 
     WHERE T1.ItemId = T2.ItemId AND T1.Date < T2.Date 
    ) 

En clair: sélectionner des lignes telles qu'il n'y a pas d'autre rangée avec le même ItemId mais plus tard Date.

0

vous pouvez utiliser le rang() également dans CTE

;With Ordered as (
    select ItemId,ShipmentId,dates, 
     rank() OVER (PARTITION by itemID ORDER By dates desc) as DateRank 
    from ItemsTable 
) 
select * from Ordered where DateRank = 1 
Questions connexes