2016-10-11 2 views
3

Ich habe ein Problem, das Ergebnis von einer SQL-Abfrage zu erhalten. Ich brauche das Ergebnis von zwei Where-Klauseln. Ich arbeite mit SQLServer2014Join 3 Tabellen mit 2 Where-Klauseln bekommen Null Ergebnisse

tabelle1: Produkt

ProductID 
1 
2 
3 
4 
5 

table2: Lieferant

SupplierID 
1 
2 
3 

table3: Product_Supplier

ProductSupplierID|ProductID|SupplierID|Reference 
1    |1  |1   |Ref001 
2    |1  |2   |Ref002 
3    |2  |1   |Ref003 
4    |3  |2   |Ref004 
5    |4  |2   |Ref005 

Was ich will, ist führen, wenn ich gesetzt:

wo (ProductID < 4) und (SupplierID = 2)

ich als Ergebnis erhalten muss: Alle Produkte unter dem ProductID 4 im Zusammenhang mit SupplierID 2, wenn dies nicht in Product_Supplier nicht vorhanden ist, muss ich Referenz = Null

ProductID|SupplierID|Reference 
1  |2   |Ref002 
2  |2   |Null 
3  |2   |Ref004 

bekomme ich einige sQL-Skript zu starten, aber ich kann nicht das richtige Ergebnis

erhalten
select a.ProductID, b.SupplierID, C.Reference from Product as a 
    left outer join Product_Supplier as c on c.ProductID= a.ProductID 
    left outer join Supplier as B on b.SupplierID = c.SupplierID 
where a.ProductID<4 and b.SupplierID=2 

Antwort von Felix Pamittan:

SELECT 
    t.*, 
    ps.Reference 
FROM (
    SELECT * 
    FROM Product 
    CROSS JOIN Supplier 
    WHERE 
     ProductID < t.ProductID 
     AND SupplierID = t.SupplierID 
) t 
LEFT JOIN Product_Supplier ps 
    ON ps.ProductID = t.ProductID 
    AND ps.SupplierID = t.SupplierID 

Auf diesem Skript kann ich nicht die Laufzeit in dem Code einzuspeisen hinzufügen. Wenn ich festlegen kann, wo am Ende der SQL-Adresse der Endbenutzer die Where-Parameter einfügen kann.

SELECT 
    t.*, 
    ps.Reference 
FROM (
    SELECT * 
    FROM Product 
    CROSS JOIN Supplier 
    --WHERE 
    -- ProductID < t.ProductID 
    -- AND SupplierID = t.SupplierID 
) t 
LEFT JOIN Product_Supplier ps 
    ON ps.ProductID = t.ProductID 
    AND ps.SupplierID = t.SupplierID 
where t.ProductID < 4 
and t.SupplierID=2 

werde ich diese letzte auf der realen Datenbank testen.

+0

SELECT * FROM Product_Supplier WHERE ProductId <4 UND SupplierID = 2' –

+0

Das Problem, das ich die zweite Reihe bekommen (2,2, null) – Ravaut123

+0

gerade richtig ich wenn ich falsch liege; Es gibt keine Tupel in Product_Supplier, wo die ProductId und SupplierId beide 2 sind ... Wenn das Tupel nicht vorhanden ist, wird es nie ausgewählt. Das heißt, wenn die Produkttabelle mit Product_Supplier verbunden wird, dann wird SupplierId gleich Null sein und ebenfalls für das Tupel mit SupplierId = 2, dann wird ProductId null sein. Ihre beste Wette könnte eine For-Schleife sein? Aber das ist ziemlich hässlich. – JonSick

Antwort

5

Sie müssen alle Kombinationen von Product s und Supplier zuerst erhalten. Tun Sie dies, indem Sie eine CROSS JOIN tun.Schließlich macht ein LEFT JOIN auf der Product_Supplier Tabelle:

SELECT 
    t.*, 
    ps.Reference 
FROM (
    SELECT * 
    FROM #Product 
    CROSS JOIN #Supplier 
    WHERE 
     ProductID < 4 
     AND SupplieIrD = 2 
) t 
LEFT JOIN #Product_Supplier ps 
    ON ps.ProductID = t.ProductID 
    AND ps.SupplierID = t.SupplieIrD 

ONLINE DEMO

+0

Ich denke, das ist auf dem richtigen Weg. Kann ich auch die where-Klauseln im t-Alias ​​setzen? – Ravaut123

+0

Was meinst du? Ich setze die 'WHERE'-Klausel in den 'CROSS JOIN', um das Ergebnis zu minimieren, bevor ein' LEFT JOIN' auf der anderen Tabelle ausgeführt wird. –

+0

siehe letzte Bearbeitung – Ravaut123

0

Try this:

SELECT ps.ProductSupplierID, s.SupplierID, ps.Reference 
FROM Product_Supplier ps 
    LEFT JOIN Product p ON ps.ProductID = p.ProductID 
    LEFT JOIN Supplier s ON ps.SupplierID = s.SupplierID 
WHERE p.ProductID < 4 
    AND s.SupplierID = 2 

Sie können in der Lage sein, um wegzukommen mit INNER JOINs statt LEFT JOINS, sondern versuchen, die LEFT JOINS ersten und ob das funktioniert, dann geben INNER JOINs einen Versuch nur um zu sehen. Sie erhalten nicht Ihre Null Werte wegen Ihrer JOINs ich glaube.

Bearbeiten Die obige Abfrage sollte Ihnen Ihre korrekten Ergebnisse geben. Sie müssen überprüfen und sicherstellen, dass Sie wirklich einen Datensatz haben, der zu Ihrer Kategorie gehört, von der Sie glauben, dass Sie sie tun. Beginnen Sie, indem Sie einige Zeilen WHERE Zeile für Zeile entfernen. Wenn Sie eine Zeile der Klausel entfernen und der Datensatz angezeigt wird, wissen Sie, dass Sie den Fehler gefunden haben.

+0

Das ist nur mein Problem, ich möchte die Nullwerte erhalten. – Ravaut123

+0

@ Ravaut123 Hat die obige Abfrage nicht funktioniert? Diese Abfrage sollte Ihnen Ihre Nullwerte geben. – James

+0

Nein, ich ändere nur p.ProductID> 4 in p.ProductID <4. Aber keine Nullwerte – Ravaut123

0

Das Problem b.SupplierID = 2 in den Kriterien ist. Weil b (Supler) auf c (Verknüpfungstabelle) verweist, negiert es den linken Join in b, wenn der Datensatz in c nicht existiert.

Sie können die criterium zum beitreten stattdessen bewegen:

select a.ProductID, b.SupplierID, C.Reference from Product as a 
    join Supplier as B on b.SupplierID = 2 -- moved criterium 
    left join Product_Supplier as c on c.ProductID= a.ProductID and c.SupplierID=b.SupplierID 
where a.ProductID<4 

Da keine expliziten Daten von supplier benötigt wird, kann man auch weglassen, dass beitreten vollständig und hard ‚2‘ in der Auswahl Teil statt (zusammen mit mit ihm als zusätzliches Kriterium in der Join)

select a.ProductID, 2, C.Reference from Product as a 
    left join Product_Supplier as c on c.ProductID= a.ProductID and c.SupplierID=2 -- moved criterium 
where a.ProductID<4