2012-03-15 9 views
9

Próbuję wyświetlić listę zmian produktu z ich zamówionymi ilościami, ALE TAKŻE pokaż wariacje produktu, w których nie ma zamówionej ilości. Pomyślałem więc, że będzie to tak proste, jak wybranie produktów i zrobienie połączenia z lewej strony na zamówieniach każdego produktu, w którym zamówienie jest aktualną wersją.Połączenie lewy/kombinacja Mysql nie działa zgodnie z oczekiwaniami

więc spodziewałem się ten kolejności operacji:

SELECT p.product_id, SUM(po.quantity) 
FROM `products` p 
LEFT JOIN `product_orders` po ON p.product_id=po.product_id 
LEFT JOIN `orders` o ON o.order_id=po.order_id AND o.is_current='1' 

ale jest coraz także ilości gdzie is_current nie jest 1 Wtedy pomyślałem, w porządku, mogę po prostu zrobić sprzężenie wewnętrzne po lewej dołącz zamiast tego w ten sposób:

SELECT p.product_id, SUM(po.quantity) 
FROM `products` p 
LEFT JOIN `product_orders` po ON p.product_id=po.product_id 
INNER JOIN `orders` o ON o.order_id=po.order_id AND o.is_current='1' 

, ale produkty, które nie zostały jeszcze zamówione, nie są wymienione. Spodziewałem się, że pojawią się jako SUMA (ilość) będąca NULL. Czy ktoś może zobaczyć, gdzie moja logika poszło nie tak? Dzięki! Scott

Odpowiedz

4

Jeśli tylko zamówienia produktów, które liczą się te, w których jest obecna, to musisz znaleźć tego podzbioru przed zrobić w lewo dołączyć do niego . W przeciwnym razie, jeśli zrobisz lewe dołączenie, otrzymasz wszystkie lub tylko te zamówione, jak odkryłeś.

Więc coś jak poniżej powinno działać:

select p.productid, sum(po.quantity) 
from products p 
left outer join (select po.productid, po.quantity 
         from productorders po 
         inner join orders o on o.orderid = po.orderid and o.iscurrent = 1) po on po.productid = p.productid 
group by p.productid 
+0

ma sens, spróbuję go ... one sec – scott

+0

Perfect, działa świetnie! ! Dokładnie to, co było potrzebne. Dzięki wielkie! – scott

+0

Bez problemu. Byłeś na dobrej drodze; Potrzebowałem tylko dodatkowego kroku. – kaj

0

Spróbuj grupowanie przez ID produktu:

SELECT p.product_id, SUM(po.quantity) 
FROM `products` p 
LEFT JOIN `product_orders` po ON p.product_id=po.product_id 
INNER JOIN `orders` o ON o.order_id=po.order_id AND o.is_current='1' 
GROUP BY p.product_id 
+0

Dzięki za odpowiedź, nadal wyświetla tylko produkty, które mają co najmniej zamówioną ilość (tak, że pojawia się w tabeli product_orders). – scott

+0

czy działa po zmianie "INNER JOIN" na "LEFT JOIN"? – Alp

+0

Tak zapytanie następnie działa, ale ja też dostaję wszystkie ilości dla is_current! = '1' wtedy (tak starsze wersje tego samego zamówienia) – scott

18

Chociaż odpowiedź kaj jest poprawna, to nie koniecznie idealny, jak MySQL ma tendencję do pominąć wykorzystanie indeksów przy użyciu tabel pochodnych (sub-wybiera). Przynajmniej to moje zrozumienie. Można nadal używać metodyki wykorzystania ŁĄCZY W przypadku umieszczenia przyłącza wewnątrz nawiasu:

SELECT p.product_id, SUM(po.quantity) 
FROM `products` p 
LEFT JOIN (`product_orders` po 
    INNER JOIN `orders` o ON o.order_id=po.order_id AND o.is_current='1') 
ON p.product_id=po.product_id; 

Wystarczy pamiętać, że klauzula ON na LEFT JOIN musi pochodzić po nawiasie. Mam nadzieję, że to pomoże!

+0

Niestety, nie używam stackoverflow bardzo często i nie wiem jak umieścić kod w swojej własnej sekcji. – Chosun

+0

Czasami przeoczam doskonały punkt, który zrobiłeś w odniesieniu do indeksów i sub-selekcji. Ładne wyjaśnienie. – mkralla11

+0

Dzięki! Robię, co mogę ... ha. – Chosun

Powiązane problemy