sql >> Database teknologi >  >> RDS >> Mysql

Sådan arbejder du med MySQL-underforespørgsler

En underforespørgsel er en SQL-forespørgsel (Structured Query Language), der er indlejret i en anden SQL-forespørgsel. Kommandoen, som underforespørgslen er indlejret i, omtales som den overordnede forespørgsel. Underforespørgsler bruges til at forbehandle data, der bruges i den overordnede forespørgsel. Underforespørgsler kan anvendes i SELECT , INSERT , OPDATERING og SLET operationer.

Når underforespørgsler udføres, behandles underforespørgslen først før den overordnede forespørgsel. Når du bygger MySQL-applikationer, giver det flere fordele at bruge underforespørgsler:

  • De opdeler SQL-sætningerne i simple logiske enheder, som kan gøre dem nemmere at forstå og vedligeholde. Med andre ord hjælper underforespørgsler med at isolere komplekse dele af forespørgsler.
  • De eliminerer behovet for at bruge kompleksUNION udsagn og JOIN udsagn.
  • De bruges til at håndhæve referenceintegritet i et scenario, hvor fremmednøgler ikke er implementeret.
  • De hjælper udviklere med at kode forretningslogik ind i MySQL-forespørgslerne.

I denne guide lærer du:

  • Sådan bruges en korreleret underforespørgsel
  • Sådan bruges en korreleret underforespørgsel i en sammenligningsoperator
  • Sådan bruges en underforespørgsel som en afledt tabel

Før du begynder

For at følge denne vejledning skal du sørge for at have følgende:

  1. Hvis du ikke allerede har gjort det, skal du oprette en Linode-konto og Compute Instance. Se vores vejledninger Kom godt i gang med Linode og Oprettelse af en beregningsinstans.

  2. Følg vores guide til konfiguration og sikring af en computerinstans for at opdatere dit system. Du ønsker måske også at indstille tidszonen, konfigurere dit værtsnavn, oprette en begrænset brugerkonto og skærpe SSH-adgang.

  3. MySQL-serversoftwaren (eller MariaDB) installeret på din Linode. Se venligst MySQL-sektionen, som indeholder vejledninger, der beskriver, hvordan du installerer MySQL på flere Linux-distributioner.

Opsætning af databasen

For at forstå, hvordan underforespørgsler fungerer, skal du først oprette en prøvedatabase. Denne eksempeldatabase bruges til at køre de forskellige eksempelforespørgsler i denne vejledning:

  1. SSH til din server og log ind på MySQL som root:

     mysql -u root -p 

    Når du bliver bedt om det, skal du indtaste root-adgangskoden til din MySQL-server og trykke på Enter at fortsætte. Bemærk, at din MySQL-servers root-adgangskode ikke er det samme som root-adgangskoden til din Linode.

    Bemærk

    Hvis din adgangskode ikke accepteres, skal du muligvis køre den forrige kommando med sudo :

    sudo mysql -u root -p 
  2. Hvis din adgangskode accepteres, bør du se MySQL-prompten:

    mysql> 
    Bemærk

    Hvis du bruger MariaDB, kan du i stedet se en prompt som følgende:

    MariaDB [(ingen)]> 
  3. For at oprette en prøvedatabase med navnet test_db , kør:

    CREATE DATABASE test_db; 

    Du bør se dette output, som bekræfter, at databasen blev oprettet:

    Forespørgsel OK, 1 række påvirket (0,01 sek.) 
  4. Skift til test_db database:

    BRUG test_db; 

    Du bør se dette output:

    Database ændret 
  5. Du har oprettet test_db og valgte det. Opret derefter en tabel med navnet kunder :

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

    Du bør se dette output:

    Forespørgsel OK, 0 rækker påvirket (0,03 sek.) 
  6. Tilføj nogle poster til kunderne bord. Kør nedenstående INSERT kommandoer én efter én:

    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'); 

    Dette output vises efter hver post er indsat:

    Forespørgsel OK, 1 række påvirket (0,00 sek.)... 
  7. Bekræft, at kundernes oplysninger blev indsat i databasen. Udfør denne SELECT kommando:

    VÆLG * FRA kunder; 

    Du bør se denne liste over kunder:

    +-------------+----------------+| kunde_id | kundenavn |+-------------+----------------+| 1 | JOHN PAUL || 2 | PETER DOE || 3 | MARY DOE || 4 | CHRISTINE JAMES || 5 | MÆRK GODT || 6 | FRANK BRIAN |+-------------+----------------+6 rækker i sæt (0,00 sek.)
  8. Opret en salg bord. Denne tabel bruger kolonnen customer_id for at henvise til kunderne tabel:

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

    Dette output vises:

    Forespørgsel OK, 0 rækker påvirket (0,03 sek.) 
  9. Udfyld derefter salg tabel med nogle poster. Kør nedenstående INSERT kommandoer én efter én:

    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'); 

    Dette output vises efter hver post er indsat:

    Forespørgsel OK, 1 række påvirket (0,01 sek.)... 
  10. Bekræft dataene i salg bord. Udfør denne SELECT kommando:

    VÆLG * FRA salg; 

    Denne liste over salgsdata skulle nu blive vist:

    +----------+-------------+-------------+| ordre_id | kunde_id | salgsbeløb |+----------+-------------+-------------+| 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 rækker i sæt (0,00 sek. )

Efter opsætning af databasen og de relaterede tabeller, kan du nu implementere de forskellige underforespørgsler i MySQL.

Sådan bruges en korreleret underforespørgsel

En korreleret underforespørgsel er en type indlejret forespørgsel, der bruger værdierne fra en overordnet forespørgsel. Disse typer forespørgsler refererer til den overordnede forespørgsel med en kolonne. Den indlejrede forespørgsel udføres én gang for hver række i den overordnede forespørgsel.

Eksemplet nedenfor præsenterer en forespørgsel, der udvælger alle kunder. Inde i forespørgslen er der en korreleret underforespørgsel, der henter det samlede salgsbeløb for hver kunde fra salg tabel.

  1. Kør eksempelforespørgslen:

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

    I dette eksempel er underforespørgslen SELECT SUM(sales_amount) FROM sales WHERE customer_id =customers.customer_id , som står i parentes.

    En liste over det samlede salg foretaget af kunder vises:

    +-------------+------------------------+---------------- ----------+| kunde_id | kundenavn | samlet_salgsbeløb |+-------------+----------------+-------------- -----+| 1 | JOHN PAUL | 125,75 || 2 | PETER DOE | 130,25 || 3 | MARY DOE | NULL || 4 | CHRISTINE JAMES | 216,55 || 5 | MÆRK GODT | 91,35 || 6 | FRANK BRIAN | NULL |+-------------+------------------------+-------------------- -----+6 rækker i sæt (0,00 sek.)

    Outputtet ovenfor fra den korrelerede underforespørgsel er i stand til at give dig en opsummeret liste over kundernes ordrer. Bemærk venligst, da customer_id s 3 og 6 ikke har nogen tilknyttede poster i salgstabellen, deres total_sales_amount er NULL .

  2. En mere elegant måde at præsentere denne liste på er at returnere 0 i stedet for NULL for kunder med nul salg. For at gøre dette skal du omslutte output genereret af underforespørgslen med en IFNULL(udtryk, 0) udmelding. Kør denne opdaterede kommando:

     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; 

    Følgende output vises. MySQL returnerer 0,00 for alle rækker, der ellers ville have returneret NULL værdier.

    +-------------+------------------------+---------------- ----------+| kunde_id | kundenavn | samlet_salgsbeløb |+-------------+----------------+-------------- -----+| 1 | JOHN PAUL | 125,75 || 2 | PETER DOE | 130,25 || 3 | MARY DOE | 0,00 || 4 | CHRISTINE JAMES | 216,55 || 5 | MÆRK GODT | 91,35 || 6 | FRANK BRIAN | 0,00 |+-------------+----------------+------------------- -----+6 rækker i sæt (0,00 sek.)

    Denne tilgang hjælper med at sikre, at outputtet ikke skader yderligere beregninger på posterne.

Sådan bruges en korreleret underforespørgsel i en sammenligningsoperatør

Underforespørgsler er nyttige til at flytte forretningslogik til databaseforespørgselsniveauet. Følgende business use-cases indeholder korrelerede underforespørgsler placeret i WHERE-sætningen af ​​en overordnet forespørgsel:

  • Overvej et scenario, hvor du gerne vil have en liste over alle kunder, der er registreret i databasen, og som ikke har tilknyttet salg. Du kan bruge en underforespørgsel sammen med MySQL-sammenligningsoperatoren NOT IN og hente disse kunder:

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

    I dette eksempel er underforespørgslen SELECT customer_id FROM sales , som står i parentes. SQL-kommandoen ovenfor udsender en liste over to kunder, der ikke findes i salgstabellen:

    +-------------+--------------+| kunde_id | kundenavn |+-------------+---------------+| 3 | MARY DOE || 6 | FRANK BRIAN |+-------------+------------+2 rækker i sæt (0,00 sek.)

    I et produktionsmiljø kan du bruge denne form for rekordsæt til at træffe bedre forretningsbeslutninger. For eksempel kan du oprette et script ved hjælp af et andet sprog som PHP eller Python for at e-maile disse kunder og spørge, om de har problemer med at placere en ordre.

  • En anden use-case er i dataoprydning. For eksempel kan du bruge en underforespørgsel til at slette kunder, der aldrig har afgivet en ordre:

     SLET FRA kunder, HVOR customer_id NOT IN (SELECT customer_id FROM sales); 

    SQL-kommandoen ovenfor sletter de to kunder og udsender følgende:

    Forespørgsel OK, 2 rækker påvirket (0,01 sek.) 

    Hvis du udfører en kommando for at liste alle kunder igen, bør disse kunder ikke længere vises i tabellen:

     VÆLG * FRA kunder; 

    Outputtet nedenfor bekræfter, at kunderne uden tilknyttede ordrer blev slettet:

    +-------------+----------------+| kunde_id | kundenavn |+-------------+----------------+| 1 | JOHN PAUL || 2 | PETER DOE || 4 | CHRISTINE JAMES || 5 | MÆRK GODT |+-------------+----------------+4 rækker i sæt (0,00 sek.)

Sådan bruges en underforespørgsel som en afledt tabel

Når underforespørgsler bruges i FROM klausul i en overordnet forespørgsel, omtales de som afledte tabeller . De er meget vigtige, når du implementerer komplekse forespørgsler, der ellers ville kræve en MySQL VIEW , JOIN eller UNION klausul. En afledt tabel findes i forespørgslen, der oprettede den, og den gemmes ikke permanent i databasen.

Når underforespørgsler bruges som afledte tabeller, isolerer de de forskellige dele af SQL-sætningen. Med andre ord giver underforespørgslen et forenklet udtryk for en tabel, der kan bruges inden for rammerne af den overordnede forespørgsel.

Bemærk Husk, at hver afledt tabel skal have alias.

Kør kommandoen nedenfor for at oprette en afledt tabelunderforespørgsel, der er kaldet order_summary :

SELECT customer_idFROM ( SELECT customer_id, count(order_id) as total_orders FROM sales group by customer_id ) as order_summaryWHERE order_summary.total_orders> 1; 
Bemærk

I denne kommando vises underforespørgslen i parentes som:

SELECTcustomer_id,count(order_id) as total_ordersFROM salesgroup by customer_id 

Ovenstående kommando forespørger salgstabellen for at bestemme kunder med mere end 1 ordre. Når du kører forespørgslen, vises dette output:

+-------------+| kunde_id |+-------------+| 1 || 2 || 5 || 4 |+-------------+4 rækker i sæt (0,00 sek.)

Ovenstående liste viser fire customer_id s, der har mere end én ordre. Som et eksempel på business use-case kan du bruge sådan en forespørgsel i et script, der belønner kunder med en bonus ved deres næste køb.

Flere oplysninger

Du ønsker måske at konsultere følgende ressourcer for yderligere oplysninger om dette emne. Selvom disse leveres i håb om, at de vil være nyttige, bemærk venligst, at vi ikke kan stå inde for nøjagtigheden eller aktualiteten af ​​eksternt hostede materialer.

  • MySQL-underforespørgsler

  1. Sådan gemmer du historiske poster i en historietabel i SQL Server

  2. Database + Windows-godkendelse + brugernavn/adgangskode?

  3. Eliminering af MySQL Split-Brain i Multi-Cloud-databaser

  4. PLSQL :NY og :GAMMEL