Wie

2010-06-21 7 views
14

eine "distinct" verbinden mit MySQL machen Ich habe zwei MySQL-Tabellen (Produkt- und Preisentwicklung), die ich anschließen möchte:Wie

Product Tabelle:

Id = int 
Name = varchar 
Manufacturer = varchar 
UPC = varchar 
Date_added = datetime 

Price_h Tabelle:

Id = int 
Product_id = int 
Price = int 
Date = datetime 

ich kann eine einfache LEFT JOIN ausführen:

SELECT Product.UPC, Product.Name, Price_h.Price, Price_h.Date 
FROM Product 
LEFT JOIN Price_h 
ON Product.Id = Price_h.Product_id; 

Aber wie erwartet, wenn ich mehr als einen Eintrag für ein Produkt in der Preisverlaufstabelle habe, bekomme ich ein Ergebnis für jeden historischen Preis.

Wie kann ein Join strukturiert werden, der nur eine Instanz jedes Produkts mit nur dem neuesten Eintrag aus der ihm zugeordneten Preisverlaufstabelle zurückgibt?

Antwort

19

Verwendung:

SELECT p.upc, 
      p.name, 
      ph.price, 
      ph.date 
    FROM PRODUCT p 
LEFT JOIN PRICE_H ph ON ph.product_id = p.id 
    JOIN (SELECT a.product_id, 
        MAX(a.date) AS max_date 
      FROM PRICE_H a 
     GROUP BY a.product_id) x ON x.product_id = ph.product_id 
           AND x.max_date = ph.date 
+0

+1: Es sollte schneller sein als meins. Obwohl längerer Code. – a1ex07

+0

Ich verstehe, warum Sie sagen, es sollte schneller sein, aber ich muss noch einen Umstand finden, wo es ist. Ich denke, dass es etwas mit der großen Anzahl von Datensätzen zu tun hat, die ich in der Preisverlaufstabelle (3.5M) habe. Vielleicht würde es helfen, wenn ich der Spalte Price_h.date einen Index hinzufügen würde? –

+2

Es scheint, dass diese Abfrage ungefähr die gleiche Menge an Zeit benötigt, egal wie viele Ergebnisse sie zurückgibt, während die Abfrage von a1ex07 bei erhöhten Ergebnissen länger dauert als erwartet. Ich war nur ein wenig überrascht darüber, wie langsam dies für kleine Ergebnismengen ist und wie schnell die Lösung von a1ex07 für die gleichen kleinen Ergebnisse ist. Da ich in der "realen Welt" mit ziemlich großen Ergebnismengen arbeiten werde, habe ich dies als Antwort gewählt. –

3

Try this:

SELECT Product.UPC, Product.Name, Price_h.Price, MAX(Price_h.Date) 
FROM Product 
INNER JOIN Price_h 
    ON Product.Id = Price_h.Product_id 
GROUP BY Product.UPC, Product.Name, Price_h.Price 
+1

Das funktionieren würde, aber es würde gib ihm die korrekte Preisentwicklung ent ry, die dem Maximum (Datum) entspricht ... – Ariel

+0

Diese Abfrage gibt Max (Datum) für jedes (Product.UPC + Product.Name + Price_h.Price) zurück. Es ist nicht der neueste Preis für das Produkt. – a1ex07

+1

Ariel und a1ex07 sind korrekt. Mit dieser Abfrage wird zwar das korrekte Datum zurückgegeben, nicht jedoch der korrekte Preis. –

3
SELECT Product.UPC, Product.Name, Price_h.Price, Price_h.Date 
FROM Product 
LEFT JOIN Price_h 
ON (Product.Id = Price_h.Product_id AND Price_h.Date = 
    (SELECT MAX(Date) FROM Price_h ph1 WHERE ph1.Product_id = Product.Id)); 
+0

+1: Obwohl kein Fan der korrelierten Unterabfrage auf der JOIN –

0
SELECT n.product_id, 
     n.product_name, 
     n.product_articul, 
     n.product_price, 
     n.product_discount, 
     n.product_description, 
     n.product_care, 
     (SELECT photo_name FROM siamm_product_photos WHERE product_id = n.product_id LIMIT 1) AS photo_name 
FROM siamm_product as n; 
0

Warum nicht halten es einfach und schnell:

SELECT 
Product.UPC, Product.Name, Price_h.Price, Price_h.Date 
FROM 
Product 
LEFT JOIN 
Price_h 
ON Product.Id = Price_h.Product_id; 
ORDER BY 
Price_h.Date DESC 
LIMIT 1