it-swarm.com.de

T-SQL-Unterabfrage max (Datum) und Verknüpfungen

Ich versuche, mehrere Tabellen zu verknüpfen, aber eine der Tabellen enthält mehrere Datensätze für eine Partid mit unterschiedlichen Datumsangaben. Ich möchte die Aufzeichnung mit dem neuesten Datum erhalten.

Hier einige Beispieltabellen:

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

Wenn ich nur den letzten Preis für ein bestimmtes Teil finden wollte, könnte ich das tun:

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

Allerdings möchte ich zuerst einen Join machen und den korrekten Preis für alle Teile zurückbekommen, nicht nur einen. Das habe ich versucht:

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

Die Ergebnisse sind falsch, da das höchste Preisdatum der gesamten Tabelle erforderlich ist.

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

Das ist fehlerhaft.

Was kann ich tun, um die gewünschten Ergebnisse zu erzielen?.

25
MaxGeek

Versuche dies:

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

Hier ist eine andere Möglichkeit, dies ohne Unterabfragen zu tun. Diese Methode übertrifft andere häufig, und es lohnt sich, beide Methoden zu testen, um herauszufinden, welche die beste Leistung liefert.

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

Dies führt zu mehreren Ergebnissen, wenn Sie zwei Preise mit demselben EXACT-Preisdatum haben (die meisten anderen Lösungen tun dies auch). Ich habe auch nichts zu berücksichtigen, wenn der letzte Preis in der Zukunft liegt. Möglicherweise möchten Sie eine Prüfung in Betracht ziehen, unabhängig davon, welche Methode Sie verwenden.

31
Tom H

Versuchen Sie, sich mit der a-Unterabfrage von MyPrice zu verbinden, um MAX(PriceDate) abzurufen:

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
KM.

Bei 2005 verwenden Sie 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
A-K

Etwas wie das

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

Wenn Sie Ihre Partid kennen oder einschränken können, fügen Sie sie in den Join ein.

   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
u07ch
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

Sie erhalten zuerst den neuesten Preis für partid (ein Standardaggregat) und fügen Sie ihn dann wieder hinzu, um die Preise zu erhalten (die nicht im Aggregat enthalten sein können). Anschließend erhalten Sie die Details zum Teil.

2
gbn

Nehmen Sie an der Preistabelle teil und wählen Sie den Eintrag für den letzten Tag aus:

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
)

Das Maximum () ist für den Fall, dass mehrere Preise pro Tag vorliegen; Ich gehe davon aus, dass Sie den höchsten Wert anzeigen möchten. Wenn Ihre Preistabelle eine ID-Spalte hat, können Sie das max () vermeiden und wie folgt vereinfachen:

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. Verwenden Sie stattdessen die Lösung von wcm!

2
Andomar

Alle anderen Antworten müssen funktionieren, aber Sie müssen dieselbe Syntax verwenden (und verstehen, warum der Fehler auftritt).

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
Eduardo Molteni

Bitte versuchen Sie folgendes Codebeispiel:

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
Rupal

Für MySQL finden Sie die folgende Abfrage:

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)

Innerhalb der Unterabfrage wird für jede Partei-ID von MyPrices ein Höchstpreis abgerufen. Anschließend wird Inner mit MyParts unter Verwendung von partid und max_pricedate verbunden.

0
Suren