Sous-requête T-SQL max (date) et jointures

J'essaye de joindre plusieurs tables, mais l'une des tables a plusieurs loggings pour un partid avec des dates différentes. Je veux get le record avec la date la plus récente.

Voici quelques exemples de tables:

Table: MyParts Partid Partnumber Description 1 ABC-123 Pipe 2 ABC-124 Handle 3 ABC-125 Light Table: MyPrices Partid Price PriceDate 1 $1 1/1/2005 1 $2 1/1/2007 1 $3 1/1/2009 2 $2 1/1/2005 2 $4 1/1/2006 2 $5 1/1/2008 3 $10 1/1/2008 3 $12 1/1/2009 

Si je voulais juste find le prix le plus récent pour une certaine partie, je pourrais faire:

 SELECT * FROM MyPrice WHERE PriceDate = (SELECT MAX(PriceDate) FROM MyPrice WHERE Partid = 1) 

Cependant, je veux d'abord faire une jointure et récupérer le prix correct pour toutes les pièces et pas seulement une. C'est ce que j'ai essayé:

 SELECT * FROM MyParts LEFT JOIN MyPrice ON MyParts.Partid = MyPrice.Partid WHERE MyPart.PriceDate = (SELECT MAX(PriceDate) FROM MyPrice) 

Les résultats sont faux car il prend la date de prix la plus élevée de la table entière.

 SELECT * FROM MyParts LEFT JOIN MyPrice ON MyParts.Partid = MyPrice.Partid WHERE MyPart.PriceDate = (SELECT MAX(PriceDate) FROM MyPrice WHERE MyPrice.Partid = MyParts.Partid) 

Que des erreurs sur.

Que puis-je faire pour get les résultats que je veux?

Essaye ça:

 Select *, Price = (Select top 1 Price From MyPrices where PartID = mp.PartID order by PriceDate desc ) from MyParts mp 

Voici une autre façon de le faire sans sous-requêtes. Cette méthode surpasse souvent les autres, il vaut donc la peine de tester les deux methods pour déterminer celles qui donnent les meilleures performances.

 SELECT PRT.PartID, PRT.PartNumber, PRT.Description, PRC1.Price, PRC1.PriceDate FROM MyParts PRT LEFT OUTER JOIN MyPrices PRC1 ON PRC1.PartID = PRT.PartID LEFT OUTER JOIN MyPrices PRC2 ON PRC2.PartID = PRC1.PartID AND PRC2.PriceDate > PRC1.PriceDate WHERE PRC2.PartID IS NULL 

Cela donnera des résultats multiples si vous avez deux prix avec le même Price Price d'EXACT (la plupart des autres solutions feront de même). Aussi, je n'ai rien à rendre count de la date du dernier prix étant dans le futur. Vous voudrez peut-être envisager une vérification pour cela, quelle que soit la méthode que vous utilisez.

Essayez de join la sous-requête de MyPrice afin de récupérer MAX(PriceDate) :

 SELECT a.*, MyPriceDate.Price, MyPriceDate.PriceDate FROM MyParts a INNER JOIN ( SELECT Partid, MAX(PriceDate) AS MaxPriceDate FROM MyPrice GROUP BY Partid ) dt ON a.Partid = dt.Partid INNER JOIN MyPrice ON dt.Partid = MyPrice.Partid AND a.PriceDate = dt.MaxPriceDate 

En 2005, utilisez ROW_NUMBER() :

 SELECT * FROM ( SELECT p.*, ROW_NUMBER() OVER(PARTITION BY Partid ORDER BY PriceDate DESC) AS rn FROM MyPrice AS p ) AS t WHERE rn=1 

Quelque chose comme ça

 SELECT * FROM MyParts LEFT JOIN ( SELECT MAX(PriceDate), PartID FROM MyPrice group by PartID ) myprice ON MyParts.Partid = MyPrice.Partid 

Si vous connaissez votre partid ou pouvez le restreindre, mettez-le dans la jointure.

  SELECT myprice.partid, myprice.partdate, myprice2.Price, * FROM MyParts LEFT JOIN ( SELECT MAX(PriceDate), PartID FROM MyPrice group by PartID ) myprice ON MyParts.Partid = MyPrice.Partid Inner Join MyPrice myprice2 on myprice2.pricedate = myprice.pricedate and myprice2.partid = myprice.partid 
 SELECT * FROM (SELECT MAX(PriceDate) AS MaxP, Partid FROM MyPrices GROUP BY Partid) MaxP JOIN MyPrices MP On MaxP.Partid = MP.Partid AND MaxP.MaxP = MP.PriceDate JOIN MyParts P ON MP.Partid = P.Partid 

Vous devez get le dernier prix pour partid en premier (un agrégat standard), puis le join pour get les prix (qui ne peuvent pas être dans l'set), suivi par l'obtention des détails de la pièce.

Inscrivez-vous sur la table des prix, puis select l'input pour le dernier jour:

 select pa.partid, pa.Partnumber, max(pr.price) from myparts pa inner join myprices pr on pr.partid = pa.partid where pr.PriceDate = ( select max(PriceDate) from myprices where partid = pa.partid ) 

Le maximum () est au cas où il y a plusieurs prix par jour; Je suppose que vous souhaitez afficher le plus élevé. Si votre tableau de prix a une colonne id, vous pouvez éviter le max () et simplifier comme:

 select pa.partid, pa.Partnumber, pr.price from myparts pa inner join myprices pr on pr.partid = pa.partid where pr.priceid = ( select max(priceid) from myprices where partid = pa.partid ) 

PS Utilisez la solution de Wcm à la place!

Toutes les autres réponses doivent fonctionner, mais en utilisant la même syntaxe (et en comprenant pourquoi l'erreur)

 SELECT * FROM MyParts LEFT JOIN MyPrice ON MyParts.Partid = MyPrice.Partid WHERE MyPart.PriceDate = (SELECT MAX(MyPrice2.PriceDate) FROM MyPrice as MyPrice2 WHERE MyPrice2.Partid = MyParts.Partid) 

S'il vous plaît essayez l'exemple de code suivant:

 select t1.*, t2.partprice, t2.partdate from myparts t1 join myprices t2 on t1.partid = t2.partid where partdate = (select max(partdate) from myprices t3 where t3.partid = t2.partid group by partid)