Ausführen mehrerer Joins in einer Abfrage in MYSQL
- Ausführen mehrerer Joins in einer Abfrage in MYSQL - Abfragekonstruktion
- Ausführen mehrerer Joins in einer Abfrage in MYSQL - Drei-Tabellen-Join mit einem natürlichen Join
-
Führen mehrere Joins in einer Abfrage in MYSQL aus - Drei-Tabellen-Join mit dem Schlüsselwort
ON
-
Mehrere Joins in einer Abfrage in MYSQL ausführen - Drei-Tabellen-Join im
WHERE
-Block - Ausführen mehrerer Joins in einer Abfrage in MYSQL - Der äußere Join-Fall
Haben Sie sich jemals gefragt, wie Sie in MySQL mehrere Joins in eine Abfrage einschließen können? Sie sind an der richtigen Stelle. Denken Sie daran, dass wir mit Joins auf Informationen in anderen Tabellen zugreifen können. Diese Informationen sind separat enthalten, um Redundanzen zu vermeiden. Betrachten wir das folgende Beispiel. Beginnen wir mit der Erstellung von drei Tabellen.
client(client_id, client_name)
definiert einen durchclient_id
identifizierten Client mit dem Namenclient_name
:
CREATE TABLE client (
client_id INT PRIMARY KEY,
client_name VARCHAR(255)
);
product(product_id, product_name, unit_price, provider_cost)
steht für ein Produkt im Geschäft, das durchproduct_id
identifiziert und alsproduct_name
bezeichnet wird und zuunit_price
verkauft wird. Die Kosten für den Kauf einer Einheit des Produkts vom Lieferanten werden durchsupplier_cost
angegeben:
CREATE TABLE product (
product_id INT PRIMARY KEY,
product_name VARCHAR(255),
unit_price INT,
supplier_cost INT
);
product_order(order_id, product_id, client_id, quantity)
stellt eine durchorder_id
identifizierte Bestellung dar, die sich auf das vom Kundenclient_id
gekaufte Produktproduct_id
mit der Mengequantity
bezieht:
CREATE TABLE product_order (
order_id INT PRIMARY KEY,
product_id INT NOT NULL,
client_id INT NOT NULL,
quantity INT NOT NULL,
FOREIGN KEY (product_id) REFERENCES product(product_id),
FOREIGN KEY (client_id) REFERENCES client(client_id)
);
Wie Sie sehen können, ist es ziemlich minimalistisch, aber es wird den Job machen. Nehmen Sie sich einen Moment Zeit, um zu bemerken, dass keine redundanten Informationen vorhanden sind. Der Produktname ist in der Tabelle product_order
nicht vorhanden. Wenn dies der Fall wäre, wäre der Name des Produkts bei jedem Kauf wiederholt worden.
Unsere Aufgabe hier ist es, den erzielten Gewinn für jeden Kunden zurückzugeben. Aus geschäftlicher Sicht können komplexere und nützlichere Abfragen vorgeschlagen werden, aber wir zeigen nur einen Mehrtabellen-Join. Sie können Ihre Datenbank mit den folgenden Werten füllen, um die Abfragen zu testen.
INSERT INTO client VALUES (1, 'John');
INSERT INTO client VALUES (2, 'Mehdi');
INSERT INTO client VALUES (3, 'Ali');
INSERT INTO product VALUES (1, 'laptop', 500, 250);
INSERT INTO product VALUES (2, 'tablet', 600, 550);
INSERT INTO product_order VALUES (1, 1, 1, 3);
INSERT INTO product_order VALUES (2, 1, 1, 3);
INSERT INTO product_order VALUES (3, 2, 2, 6);
Ausführen mehrerer Joins in einer Abfrage in MYSQL - Abfragekonstruktion
Der mit einer Bestellung verbundene Gewinn wird wie folgt berechnet:
$$profit = quantity * (unit\_price - supplier\_cost)$$
Wie Sie sehen, benötigen wir für unsere Zielabfrage drei Werte. Die Menge findet sich in product_order
, der Einzelpreis und die Lieferantenkosten finden sich in product
und schliesslich findet man den Kundennamen in client
. Daher ist ein Drei-Tabellen-Join erforderlich. Wir geben die Abfrageergebnisse nach jeder Abfrage.
Ausführen mehrerer Joins in einer Abfrage in MYSQL - Drei-Tabellen-Join mit einem natürlichen Join
Die Fremdschlüssel in den verschiedenen Tabellen haben standardmäßig denselben Namen wie die referenzierten Primärschlüssel. Wir können einen natürlichen Join verwenden, um die drei Tabellen wie folgt zu verknüpfen.
SELECT client_name, SUM(quantity * (unit_price - supplier_cost)) AS profit
FROM product_order
NATURAL JOIN product
NATURAL JOIN client
GROUP BY client_id;
Ausgabe:
| client_name | profit |
| ----------- | ------ |
| John | 1500 |
| Mehdi | 300 |
Führen mehrere Joins in einer Abfrage in MYSQL aus - Drei-Tabellen-Join mit dem Schlüsselwort ON
Es gibt noch eine andere Möglichkeit, unser Ziel zu erreichen. Wir können das Schlüsselwort ON
verwenden wie in:
SELECT client_name, SUM(product_order.quantity * (product.unit_price - product.supplier_cost)) AS profit
FROM product_order
JOIN product
ON product_order.product_id = product.product_id
JOIN client
ON product_order.client_id = client.client_id
GROUP BY client.client_id;
Ausgabe:
| client_name | profit |
| ----------- | ------ |
| John | 1500 |
| Mehdi | 300 |
Mehrere Joins in einer Abfrage in MYSQL ausführen - Drei-Tabellen-Join im WHERE
-Block
Schließlich können die Bedingungen, unter denen die Joins durchgeführt werden, in den WHERE
-Block selbst aufgenommen werden.
SELECT client_name, SUM(product_order.quantity * (product.unit_price - product.supplier_cost)) AS profit
FROM product_order
JOIN product
JOIN client
WHERE product_order.product_id = product.product_id
AND product_order.client_id = client.client_id
GROUP BY client.client_id;
Ausgabe:
| client_name | profit |
| ----------- | ------ |
| John | 1500 |
| Mehdi | 300 |
Ausführen mehrerer Joins in einer Abfrage in MYSQL - Der äußere Join-Fall
Denken Sie daran, dass ein Join unter Bedingungen der Gleichheit zwischen Attributen ausgeführt wird. Wenn in bestimmten Zeilen der Tabellen keine solche Gleichheit besteht, wird die kombinierte Zeile nicht in den resultierenden Join aufgenommen (der innere Join ist der Standard).
Dies kann problematisch sein.
Für die obige Abfrage würden die Kunden, die in der Datenbank vorhanden sind, aber nie ein Produkt gekauft haben, nicht im Ergebnis erscheinen. Sie haben keine zugehörigen Zeilen in der Tabelle product_order
, wie in der Abbildung unten gezeigt.
Ein solcher Fall kann auftreten, wenn eine Webanwendung verwendet wird, bei der einige Kunden ein Konto erstellt, aber noch nichts gekauft haben. Eine Lösung wäre die Verwendung eines LEFT OUTER JOIN
, bei dem Kunden ohne vorherige Bestellungen mit NULL
product_order
-Attributen verknüpft werden.
Die letzte Abfrage lautet:
SELECT client_name, SUM(IFNULL(quantity, 0) * (IFNULL(unit_price, 0) - IFNULL(supplier_cost, 0))) AS profit
FROM client
LEFT OUTER JOIN product_order
ON product_order.client_id = client.client_id
LEFT OUTER JOIN product
ON product.product_id = product_order.product_id
GROUP BY client.client_id;
Ausgabe:
| client_name | profit |
| ----------- | ------ |
| John | 1500 |
| Mehdi | 300 |
| Ali | 0 |
Wie oben erwähnt, werden die Tabellenattribute product_order
inklusive der Menge auf NULL
gesetzt, wenn für den aktuellen Kunden keine Bestellung vorliegt – das gleiche gilt für die Tabellenattribute product
. Wenn wir für diese Kunden einen Gewinnwert von Null wünschen, können wir den Mengenwert NULL
mit der Funktion IFNULL
auf Null umwandeln.
Das gleiche gilt für unit_price
und supply_cost
. Jeder andere Standardwert als 0
kann verwendet werden. Klicken Sie hier für Details zur Funktion IFNULL
.
In der Abbildung unten zeigen wir, wie sich die innere Verbindung mit der äußeren vergleicht.