Mysql
 sql >> Datenbank >  >> RDS >> Mysql

So arbeiten Sie mit MySQL-Unterabfragen

Eine Unterabfrage ist eine SQL-Abfrage (Structured Query Language), die in einer anderen SQL-Abfrage verschachtelt ist. Der Befehl, in dem die Unterabfrage verschachtelt ist, wird als übergeordnete Abfrage bezeichnet. Unterabfragen werden verwendet, um Daten vorzuverarbeiten, die in der übergeordneten Abfrage verwendet werden. Unterabfragen können in SELECT angewendet werden , INSERT , UPDATE , und DELETE Operationen.

Wenn Unterabfragen ausgeführt werden, wird die Unterabfrage zuerst vor der übergeordneten Abfrage verarbeitet. Beim Erstellen von MySQL-Anwendungen bietet die Verwendung von Unterabfragen mehrere Vorteile:

  • Sie unterteilen die SQL-Anweisungen in einfache logische Einheiten, wodurch sie leichter zu verstehen und zu warten sind. Mit anderen Worten, Unterabfragen helfen dabei, komplexe Teile von Abfragen zu isolieren.
  • Sie beseitigen die Notwendigkeit, komplexeUNION zu verwenden Anweisungen undJOIN Aussagen.
  • Sie werden verwendet, um die referenzielle Integrität in einem Szenario zu erzwingen, in dem keine Fremdschlüssel implementiert sind.
  • Sie helfen Entwicklern, Geschäftslogik in die MySQL-Abfragen zu codieren.

In diesem Handbuch erfahren Sie:

  • So verwenden Sie eine korrelierte Unterabfrage
  • Verwendung einer korrelierten Unterabfrage in einem Vergleichsoperator
  • So verwenden Sie eine Unterabfrage als abgeleitete Tabelle

Bevor Sie beginnen

Um dieser Anleitung zu folgen, stellen Sie sicher, dass Sie Folgendes haben:

  1. Wenn Sie dies noch nicht getan haben, erstellen Sie ein Linode-Konto und eine Compute-Instanz. Sehen Sie sich unsere Leitfäden Erste Schritte mit Linode und Erstellen einer Compute-Instanz an.

  2. Folgen Sie unserem Leitfaden zum Einrichten und Sichern einer Compute-Instanz, um Ihr System zu aktualisieren. Möglicherweise möchten Sie auch die Zeitzone festlegen, Ihren Hostnamen konfigurieren, ein eingeschränktes Benutzerkonto erstellen und den SSH-Zugriff sichern.

  3. Die MySQL-Serversoftware (oder MariaDB), die auf Ihrem Linode installiert ist. Bitte lesen Sie den MySQL-Abschnitt, der Anleitungen enthält, die beschreiben, wie MySQL auf mehreren Linux-Distributionen installiert wird.

Einrichten der Datenbank

Um zu verstehen, wie Unterabfragen funktionieren, erstellen Sie zunächst eine Beispieldatenbank. Diese Beispieldatenbank wird verwendet, um die verschiedenen Beispielabfragen in diesem Handbuch auszuführen:

  1. SSH zu Ihrem Server und melden Sie sich als root bei MySQL an:

     mysql -u root -p
    

    Wenn Sie dazu aufgefordert werden, geben Sie das Root-Passwort Ihres MySQL-Servers ein und drücken Sie Enter weitermachen. Beachten Sie, dass das Root-Passwort Ihres MySQL-Servers nicht dasselbe ist wie das Root-Passwort für Ihr Linode.

    Hinweis

    Wenn Ihr Passwort nicht akzeptiert wird, müssen Sie möglicherweise den vorherigen Befehl mit sudo ausführen :

    sudo mysql -u root -p
    
  2. Wenn Ihr Passwort akzeptiert wird, sollten Sie die MySQL-Eingabeaufforderung sehen:

    
    mysql >
    
    Hinweis

    Wenn Sie MariaDB verwenden, sehen Sie möglicherweise stattdessen eine Eingabeaufforderung wie die folgende:

    
    MariaDB [(none)]>
    
  3. So erstellen Sie eine Beispieldatenbank mit dem Namen test_db , ausführen:

    CREATE DATABASE test_db;
    

    Sie sollten diese Ausgabe sehen, die bestätigt, dass die Datenbank erfolgreich erstellt wurde:

    
    Query OK, 1 row affected (0.01 sec)
    
  4. Wechseln Sie zur test_db Datenbank:

    USE test_db;
    

    Sie sollten diese Ausgabe sehen:

    
    Database changed
    
  5. Sie haben die test_db erstellt und es ausgewählt. Erstellen Sie als Nächstes eine Tabelle mit dem Namen customers :

     CREATE TABLE customers
     (
     customer_id BIGINT PRIMARY KEY AUTO_INCREMENT,
     customer_name VARCHAR(50)
     ) ENGINE = InnoDB;
    

    Sie sollten diese Ausgabe sehen:

    
    Query OK, 0 rows affected (0.03 sec)
    
  6. Fügen Sie den customers einige Datensätze hinzu Tisch. Führen Sie das folgende INSERT aus Befehle nacheinander:

    INSERT INTO customers(customer_name) VALUES ('JOHN PAUL');
    INSERT INTO customers(customer_name) VALUES ('PETER DOE');
    INSERT INTO customers(customer_name) VALUES ('MARY DOE');
    INSERT INTO customers(customer_name) VALUES ('CHRISTINE JAMES');
    INSERT INTO customers(customer_name) VALUES ('MARK WELL');
    INSERT INTO customers(customer_name) VALUES ('FRANK BRIAN');
    

    Diese Ausgabe wird nach dem Einfügen jedes Datensatzes angezeigt:

    
    Query OK, 1 row affected (0.00 sec)
    ...
    
  7. Überprüfen Sie, ob die Kundeninformationen in die Datenbank eingefügt wurden. Führen Sie dieses SELECT aus Befehl:

    SELECT * FROM customers;
    

    Sie sollten diese Kundenliste sehen:

    
    +-------------+-----------------+
    | customer_id | customer_name   |
    +-------------+-----------------+
    |           1 | JOHN PAUL       |
    |           2 | PETER DOE       |
    |           3 | MARY DOE        |
    |           4 | CHRISTINE JAMES |
    |           5 | MARK WELL       |
    |           6 | FRANK BRIAN     |
    +-------------+-----------------+
    6 rows in set (0.00 sec)
    
  8. Erstellen Sie einen sales Tisch. Diese Tabelle verwendet die Spalte customer_id um auf die customers zu verweisen Tabelle:

    CREATE TABLE sales
    (
    order_id BIGINT PRIMARY KEY AUTO_INCREMENT,
    customer_id BIGINT,
    sales_amount DECIMAL(17,2)
    ) ENGINE = InnoDB;
    

    Diese Ausgabe erscheint:

    
    Query OK, 0 rows affected (0.03 sec)
    
  9. Füllen Sie als Nächstes die sales aus Tabelle mit einigen Aufzeichnungen. Führen Sie das folgende INSERT aus Befehle nacheinander:

    INSERT INTO sales (customer_id, sales_amount) VALUES ('1','25.75');
    INSERT INTO sales (customer_id, sales_amount) VALUES ('2','85.25');
    INSERT INTO sales (customer_id, sales_amount) VALUES ('5','3.25');
    INSERT INTO sales (customer_id, sales_amount) VALUES ('4','200.75');
    INSERT INTO sales (customer_id, sales_amount) VALUES ('5','88.10');
    INSERT INTO sales (customer_id, sales_amount) VALUES ('1','100.00');
    INSERT INTO sales (customer_id, sales_amount) VALUES ('2','45.00');
    INSERT INTO sales (customer_id, sales_amount) VALUES ('4','15.80');
    

    Diese Ausgabe wird nach dem Einfügen jedes Datensatzes angezeigt:

    
    Query OK, 1 row affected (0.01 sec)
    ...
    
  10. Überprüfen Sie die Daten in den sales Tisch. Führen Sie dieses SELECT aus Befehl:

    SELECT * FROM sales;
    

    Diese Liste mit Verkaufsdaten sollte jetzt angezeigt werden:

    
    +----------+-------------+--------------+
    | order_id | customer_id | sales_amount |
    +----------+-------------+--------------+
    |        1 |           1 |        25.75 |
    |        2 |           2 |        85.25 |
    |        3 |           5 |         3.25 |
    |        4 |           4 |       200.75 |
    |        5 |           5 |        88.10 |
    |        6 |           1 |       100.00 |
    |        7 |           2 |        45.00 |
    |        8 |           4 |        15.80 |
    +----------+-------------+--------------+
    8 rows in set (0.00 sec)
    

Nachdem Sie die Datenbank und die zugehörigen Tabellen eingerichtet haben, können Sie nun die verschiedenen Unterabfragen in MySQL implementieren.

So verwenden Sie eine korrelierte Unterabfrage

Eine korrelierte Unterabfrage ist eine Art verschachtelte Abfrage, die die Werte einer übergeordneten Abfrage verwendet. Diese Arten von Abfragen verweisen mit einer Spalte auf die übergeordnete Abfrage. Die verschachtelte Abfrage wird einmal für jede Zeile in der übergeordneten Abfrage ausgeführt.

Das folgende Beispiel zeigt eine Abfrage, die alle Kunden auswählt. Innerhalb der Abfrage gibt es eine korrelierte Unterabfrage, die den Gesamtumsatzbetrag für jeden Kunden aus sales abruft Tabelle.

  1. Führen Sie die Beispielabfrage aus:

    SELECT
    customer_id,
    customer_name,
    (SELECT SUM(sales_amount)
    FROM sales WHERE customer_id = customers.customer_id) as total_sales_amount
    FROM
    customers;
    

    In diesem Beispiel lautet die Unterabfrage SELECT SUM(sales_amount) FROM sales WHERE customer_id = customers.customer_id , das in Klammern steht.

    Eine Liste der Gesamtumsätze der Kunden wird angezeigt:

    
    +-------------+-----------------+--------------------+
    | customer_id | customer_name   | total_sales_amount |
    +-------------+-----------------+--------------------+
    |           1 | JOHN PAUL       |             125.75 |
    |           2 | PETER DOE       |             130.25 |
    |           3 | MARY DOE        |               NULL |
    |           4 | CHRISTINE JAMES |             216.55 |
    |           5 | MARK WELL       |              91.35 |
    |           6 | FRANK BRIAN     |               NULL |
    +-------------+-----------------+--------------------+
    6 rows in set (0.00 sec)
    

    Die obige Ausgabe der korrelierten Unterabfrage kann Ihnen eine zusammengefasste Liste der Kundenbestellungen liefern. Bitte beachten, da customer_id s 3 und 6 haben keine zugeordneten Datensätze in der Verkaufstabelle, deren total_sales_amount ist NULL .

  2. Eine elegantere Art, diese Liste darzustellen, ist die Rückgabe von 0 statt NULL für die Kunden mit null Umsatz. Umschließen Sie dazu die von der Unterabfrage generierte Ausgabe mit einem IFNULL(expression, 0) Erklärung. Führen Sie diesen aktualisierten Befehl aus:

     SELECT
     customer_id,
     customer_name,
     IFNULL((SELECT SUM(sales_amount)
     FROM sales WHERE customer_id = customers.customer_id), 0) as total_sales_amount
     FROM
     customers;
    

    Es erscheint die folgende Ausgabe. MySQL gibt 0,00 für alle Zeilen zurück, die sonst NULL zurückgegeben hätten Werte.

    
    +-------------+-----------------+--------------------+
    | customer_id | customer_name   | total_sales_amount |
    +-------------+-----------------+--------------------+
    |           1 | JOHN PAUL       |             125.75 |
    |           2 | PETER DOE       |             130.25 |
    |           3 | MARY DOE        |               0.00 |
    |           4 | CHRISTINE JAMES |             216.55 |
    |           5 | MARK WELL       |              91.35 |
    |           6 | FRANK BRIAN     |               0.00 |
    +-------------+-----------------+--------------------+
    6 rows in set (0.00 sec)
    

    Dieser Ansatz trägt dazu bei, dass die Ausgabe keine weiteren Berechnungen in den Datensätzen beeinträchtigt.

So verwenden Sie eine korrelierte Unterabfrage in einem Vergleichsoperator

Unterabfragen sind nützlich, um Geschäftslogik in die Datenbankabfrageebene zu verschieben. Die folgenden geschäftlichen Anwendungsfälle weisen korrelierte Unterabfragen auf, die in der WHERE-Klausel einer übergeordneten Abfrage platziert werden:

  • Stellen Sie sich ein Szenario vor, in dem Sie eine Liste aller in der Datenbank registrierten Kunden erhalten möchten, denen keine Verkäufe zugeordnet sind. Sie können eine Unterabfrage zusammen mit dem MySQL-Vergleichsoperator NOT IN verwenden und diese Kunden abrufen:

      SELECT
      customer_id,
      customer_name
      FROM
      customers
      WHERE customer_id NOT IN (SELECT customer_id FROM sales);
    

    In diesem Beispiel lautet die Unterabfrage SELECT customer_id FROM sales , die in Klammern steht. Der obige SQL-Befehl gibt eine Liste mit zwei Kunden aus, die nicht in der Verkaufstabelle gefunden werden:

    
    +-------------+---------------+
    | customer_id | customer_name |
    +-------------+---------------+
    |           3 | MARY DOE      |
    |           6 | FRANK BRIAN   |
    +-------------+---------------+
    2 rows in set (0.00 sec)
    

    In einer Produktionsumgebung können Sie diese Art von Datensätzen verwenden, um bessere Geschäftsentscheidungen zu treffen. Sie können beispielsweise ein Skript mit einer anderen Sprache wie PHP oder Python erstellen, um diesen Kunden eine E-Mail zu senden und zu fragen, ob sie ein Problem bei der Bestellung haben.

  • Ein weiterer Anwendungsfall ist die Datenbereinigung. Beispielsweise können Sie eine Unterabfrage verwenden, um Kunden zu löschen, die noch nie eine Bestellung aufgegeben haben:

      DELETE
      FROM
      customers
      WHERE customer_id NOT IN (SELECT customer_id FROM sales);
    

    Der obige SQL-Befehl löscht die beiden Kunden und gibt Folgendes aus:

    
    Query OK, 2 rows affected (0.01 sec)
    

    Wenn Sie einen Befehl zum erneuten Auflisten aller Kunden ausführen, sollten diese Kunden nicht mehr in der Tabelle erscheinen:

      SELECT *
      FROM
      customers;
    

    Die folgende Ausgabe bestätigt, dass die Kunden ohne zugeordnete Bestellungen gelöscht wurden:

    
    +-------------+-----------------+
    | customer_id | customer_name   |
    +-------------+-----------------+
    |           1 | JOHN PAUL       |
    |           2 | PETER DOE       |
    |           4 | CHRISTINE JAMES |
    |           5 | MARK WELL       |
    +-------------+-----------------+
    4 rows in set (0.00 sec)
    

So verwenden Sie eine Unterabfrage als abgeleitete Tabelle

Wenn Unterabfragen im FROM verwendet werden -Klausel einer übergeordneten Abfrage, werden sie als abgeleitete Tabellen bezeichnet . Sie sind sehr wichtig, wenn komplexe Abfragen implementiert werden, die andernfalls eine MySQL VIEW erfordern würden , JOIN , oder UNION Klausel. Eine abgeleitete Tabelle existiert in der Abfrage, die sie erstellt hat, und wird nicht dauerhaft in der Datenbank gespeichert.

Wenn Unterabfragen als abgeleitete Tabellen verwendet werden, isolieren sie die verschiedenen Teile der SQL-Anweisung. Mit anderen Worten, die Unterabfrage stellt einen vereinfachten Ausdruck einer Tabelle bereit, die im Rahmen der übergeordneten Abfrage verwendet werden kann.

Hinweis Denken Sie daran, dass jede abgeleitete Tabelle mit einem Alias ​​versehen werden muss.

Führen Sie den folgenden Befehl aus, um eine abgeleitete Tabellenunterabfrage mit dem Alias ​​order_summary zu erstellen :

SELECT customer_id
FROM
    (
    SELECT
    customer_id,
    count(order_id) as total_orders
    FROM sales
    group by customer_id
    ) as order_summary
WHERE order_summary.total_orders > 1;
Hinweis

In diesem Befehl erscheint die Unterabfrage in Klammern als:

SELECT
customer_id,
count(order_id) as total_orders
FROM sales
group by customer_id

Der obige Befehl fragt die Verkaufstabelle ab, um Kunden mit mehr als einer Bestellung zu ermitteln. Wenn Sie die Abfrage ausführen, wird diese Ausgabe angezeigt:


+-------------+
| customer_id |
+-------------+
|           1 |
|           2 |
|           5 |
|           4 |
+-------------+
4 rows in set (0.00 sec)

Die obige Liste zeigt vier customer_id s, die mehr als eine Bestellung haben. Als Beispiel für einen geschäftlichen Anwendungsfall können Sie eine solche Abfrage in einem Skript verwenden, das Kunden bei ihrem nächsten Einkauf mit einem Bonus belohnt.

Weitere Informationen

Weitere Informationen zu diesem Thema finden Sie in den folgenden Ressourcen. Obwohl diese in der Hoffnung bereitgestellt werden, dass sie nützlich sind, beachten Sie bitte, dass wir nicht für die Genauigkeit oder Aktualität extern gehosteter Materialien garantieren können.

  • MySQL-Unterabfragen