2016-05-18 8 views
1

Die folgende Abfrage ist für mich verwirrend. Es tut nicht zeigen Sie alle Zeilen in der products Tabelle, wenn ich WHERE (inventory_to_pos.POSID IS NULL OR inventory_to_pos.POSID = ?) tun und binden Sie eine POSID, die möglicherweise in inventory_to_pos nicht vorhanden sein kann. Wenn LEFT JOIN eine Tabelle, sollte ich nicht alle Zeilen aus der ursprünglichen Tabelle, wenn ich nur auf die ursprüngliche Tabelle filtern und verwenden IS NULL unter allen Bedingungen für LEFT JOIN 'ed Tabellen?LEFT JOIN löscht Zeilen ohne ursprüngliche Tabelle zu filtern

SELECT products.ID,products.NAME,products.VOLUME,productcombinations.PRODUCTID,productcombinations.PART,inventory_to_pos.FULLCOUNT 
FROM products 
LEFT JOIN productcombinations ON products.ID = productcombinations.PARTOF 
LEFT JOIN inventory_to_pos ON products.ID = inventory_to_pos.PRODUCT 
WHERE products.INVENTORY = 1 
AND products.AVAILABLE = 1 
AND products.ID > 0 
AND (inventory_to_pos.POSID IS NULL OR inventory_to_pos.POSID = ?); 

In dem Fall, wo inventory_to_pos.PRODUCT und inventory_to_pos.POSID nicht für das angegebene Produkt und POSID existieren, ich bin keine Zeilen gegeben. Warum?

+0

LEFT JOIN + WHERE = INNER (über gleiche Tabelle) JOIN, so setzen diese zusätzlichen condititions in LEFT JOIN-Anweisung. – mitkosoft

+0

Wie ist das gleich? Ich verwende nicht WHERE in der Spalte, die links verbunden ist? Können Sie ein Beispiel dafür zeigen, was Sie meinen? – nickdnk

+0

Sie versuchen 'WHERE inventory_to_pos.POSID ist NULL', richtig? – mitkosoft

Antwort

1

Verschieben alle zugehörigen invetory_to_pos Klauseln in LEFT JOIN, d.h .:

SELECT 
    products.ID, 
    products. NAME, 
    products.VOLUME, 
    productcombinations.PRODUCTID, 
    productcombinations.PART, 
    inventory_to_pos.FULLCOUNT 
FROM 
    products 
LEFT JOIN productcombinations ON products.ID = productcombinations.PARTOF 
LEFT JOIN inventory_to_pos ON products.ID = inventory_to_pos.PRODUCT AND (
    inventory_to_pos.POSID IS NULL 
    OR inventory_to_pos.POSID = ? 
) 
WHERE 
    products.INVENTORY = 1 
AND products.AVAILABLE = 1 
AND products.ID > 0 
+0

Es hat funktioniert. Beeindruckend. Dies ist eine große Lücke in meinem allgemeinen Wissen darüber, wie man Joins filtern kann. – nickdnk

+0

Kannst du mir vielleicht erklären * warum * wir können nicht in WHERE filtern? Ich hatte immer den Eindruck, dass hier alle Filter verschwinden sollten. – nickdnk

+0

Da MySQL zuerst die Tabellen selbst filtert (es braucht alle WHERE-Anweisungen), führt man den Join durch. In Ihrem Fall filtert die Engine zuerst "inventory_to_pos" basierend auf Ihren WHERE-Klauseln und wird dann JOIN, was gleich INNER JOIN ist. – mitkosoft