T-SQL Sousquery Max(Date) et jointures

j'essaie de joindre plusieurs tables, mais une des tables a plusieurs enregistrements pour une partid avec des dates différentes. Je veux obtenir l'enregistrement avec la date la plus récente.

voici quelques exemples de tableaux:

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/2005
1                   1/1/2007
1                   1/1/2009
2                   1/1/2005
2                   1/1/2006
2                   1/1/2008
3                  1/1/2008
3                  1/1/2009

si je voulais juste trouver 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 faire une jointure d'abord et obtenir le prix correct pour toutes les pièces pas seulement un. 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 erronés 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.

Que puis-je faire pour obtenir les résultats que je veux.

25
demandé sur Cade Roux 2009-05-18 22:25:47

10 réponses

essaye ceci:

Select *,
    Price = (Select top 1 Price 
             From MyPrices 
             where PartID = mp.PartID 
             order by PriceDate desc
            )
from MyParts mp
31
répondu wcm 2009-05-18 19:29:31

Voici une autre façon de le faire sans sous-séries. Cette méthode sera souvent plus performante que les autres, il est donc intéressant de tester les deux méthodes pour voir ce qui donne la meilleure performance.

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 prix EXACT (la plupart des autres solutions feront la même chose). En outre, I il n'y a rien à rendre compte de la date du dernier prix étant dans le futur. Vous pouvez envisager de vérifier que quelle que soit la méthode que vous en fin de utiliser.

31
répondu Tom H 2009-05-18 21:00:20

Essayez de vous joindre à l'une sous-requête 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
10
répondu KM. 2016-07-27 17:42:39

en 2005 utiliser 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
5
répondu A-K 2011-10-29 08:28:48

quelque Chose comme ceci

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 à l'intérieur de 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
4
répondu u07ch 2009-05-18 18:55:06
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 obtenir le dernier pricedate pour partid d'abord (un agrégat standard), puis le rejoindre pour obtenir les prix (qui ne peuvent pas être dans l'agrégat), suivie par obtenir les détails de la pièce.

2
répondu gbn 2009-05-18 18:38:08

Rejoindre sur le tableau des prix, puis sélectionnez l'entrée 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 max () est au cas où il y a plusieurs prix par jour; je suppose que vous voulez afficher le plus élevé. Si votre table 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
)
2
répondu Andomar 2009-05-18 18:49:52

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)
1
répondu Eduardo Molteni 2009-05-18 18:45:11

s'il vous Plaît essayer la prochaine exemple de code:

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)
0
répondu Rupal 2017-11-08 08:08:24

Pour MySQL, veuillez trouver ci-dessous la requête:

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-commande il va chercher max pricedate pour chaque partyid de MyPrices alors, liaison interne avec MyParts en utilisant partid et le max_pricedate

0
répondu Suren 2018-06-25 00:36:29