J'essaie de joindre plusieurs tables, mais l'une des tables a plusieurs enregistrements pour un partid avec des dates différentes. Je veux obtenir l'enregistrement 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 trouver le prix le plus récent pour une certaine partie, je pourrais le 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, 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 incorrects 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)
C'est une erreur.
Que puis-je faire pour obtenir les résultats souhaités?.
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 surpassera souvent les autres, il est donc intéressant de tester les deux méthodes pour déterminer laquelle offre 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 plusieurs résultats si vous avez deux prix avec le même EXACT PriceDate (la plupart des autres solutions feront la même chose). De plus, rien ne permet de rendre compte de la dernière date de fixation du prix dans l’avenir. Vous voudrez peut-être envisager une vérification, quelle que soit la méthode utilisée.
Essayez de rejoindre 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 si vous pouvez le restreindre, placez-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 d'abord obtenir le dernier prix pour Partid (un agrégat standard), puis le rejoindre pour obtenir les prix (qui ne peuvent pas être globaux), puis les détails de la pièce.
Inscrivez-vous sur la table des prix, puis sélectionnez l'entrée du 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 max () est dans le cas où il y a plusieurs prix par jour; Je suppose que vous souhaitez afficher le plus élevé. Si votre table de prix a une colonne id, vous pouvez éviter max () et simplifier comme ceci:
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
)
P.S. Utilisez plutôt la solution de wcm!
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)
Veuillez essayer 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)
Pour MySQL, veuillez trouver la requête ci-dessous:
select * from (select PartID, max(Pricedate) max_pricedate from MyPrices group bu partid) as a
inner join MyParts b on
(a.partid = b.partid and a.max_pricedate = b.pricedate)
À l'intérieur de la sous-requête, il obtient un prix maximal pour chaque partie de MyPrices, puis, Une jonction interne avec MyParts à l'aide de partid et du max_pricedate