MySQL Delspørring med eksempler

⚡ Smart oppsummering

MySQL SubQuery-syntaks plasserer én SELECT-setning inni en annen, slik at det indre resultatet mater den ytre spørringen. Denne forklaringen dekker skalar-, rad- og tabellunderspørringer, utførelsesrekkefølge, praktiske eksempler og ytelsesavveiningen mot JOIN-operasjoner.

  • 🔍 Kjernedefinisjon: En delspørring er en SELECT-setning som er nestet i en annen spørring, og den indre spørringen kjøres først for å levere verdier til den ytre spørringen.
  • 🧮 Skalar delspørring: Returnerer én rad og én kolonne, slik at den pares med sammenligningsoperatorer som lik, større enn eller mindre enn.
  • ???? Underspørringer for rader og tabeller: En radunderspørring returnerer én rad med flere kolonner, mens en tabellunderspørring returnerer mange rader og fungerer med IN-operatoren.
  • 🧩 Hekkedybde: Delspørringer kan nestes flere nivåer dypt, noe som lokaliserer verdier som det høyest betalende medlemmet i én setning.
  • ✍️ Utover SELECT: INSERT-, UPDATE- og DELETE-setninger godtar delspørringer, noe som gjør det mulig å gjøre masseendringer uten midlertidige tabeller.
  • Ytelsesregel: En JOIN kjører vanligvis mye raskere enn en tilsvarende delspørring, så reserver delspørringer for logikk som en JOIN ikke kan uttrykke.

MySQL Undersøk

Hva er en delspørring i SQL?

A undersøkelse er en SELECT-spørring som finnes i en annen spørring. Den indre SELECT-spørringen brukes vanligvis til å bestemme resultatene av den ytre SELECT-spørringen, slik at databasen evaluerer den indre setningen først og deretter sender utdataene oppover.

Den indre spørringen kalles indre spørring eller nestet spørring, og setningen som inneholder den kalles ytre spørringLa oss se på syntaksen for underspørringen.

MySQL Undersøk

Diagrammet ovenfor viser den generelle formen på setningen: den ytre SELECT-klausulen angir kolonnene du vil se, og den indre SELECT-klausulen i parentes angir verdien eller listen over verdier som WHERE-klausulen sammenlignes med.

Hvorfor bruke en delspørring?

Før vi ser på de forskjellige typene, er det nyttig å vite når en delspørring fortjener sin plass i en setning.

En delspørring svarer på et spørsmål der filterverdien ikke er kjent på forhånd. Den må beregnes fra selve dataene. En vanlig kundeklage hos MyFlix Video Library er det lave antallet filmtitler, og ledelsen ønsker å kjøpe filmer for kategorien som har færrest titler. Ingen vet hvilken kategori det er før databasen blir spurt, så verdien må beregnes først og deretter brukes som et filter.

Delspørringer er påtractiv av tre praktiske grunner:

  • lesbarhet: Hver del av logikken sitter i sin egen blokk i parentes, så utsagnet leses som en sekvens av små spørsmål i stedet for ett komplekst uttrykk.
  • Isolasjon: En intern spørring kan kjøres på egenhånd for å bekrefte at den returnerer forventet verdi, noe som gjør testing og feilsøking mye enklere.
  • Fleksibilitet: Det samme mønsteret fungerer i WHERE-, HAVING-, SELECT- og FROM-klausulene, og også i INSERT-, UPDATE- og DELETE-setninger.

Avveiningen er hastighet, som undersøkes i JOIN-sammenligningen senere i denne artikkelen.

Typer av delspørringer i MySQL

MySQL støtter tre typer delspørringer, og typen bestemmes av formen på resultatet som den indre spørringen returnerer. Hver type forklares nedenfor med et fungerende eksempel mot myflixdb-databasen.

1) Skalar delspørring

A skalar delspørring returnerer nøyaktig én rad og én kolonne, som betyr at den returnerer én enkelt verdi. Fordi resultatet er én enkelt verdi, kan den brukes overalt hvor en bokstavelig verdi er tillatt. For å gå tilbake til MyFlix-problemet ovenfor, kan du bruke en spørring som denne:

SELECT category_name FROM categories
WHERE category_id = (SELECT MIN(category_id) FROM movies);

Det gir et resultat:

MySQL Undersøk

La oss se hvordan denne spørringen fungerer.

MySQL Undersøk

Som utførelsesdiagrammet viser, MySQL første løp SELECT MIN(category_id) FROM movies, mottar én verdi, og kjører først deretter den ytre spørringen med den verdien på plass. Fordi én enkelt verdi returneres, er de tillatte operatorene standard sammenligningssettet: =, <> (eller !=), >, >=, <og <=.

💡 Tips: Hvis en delspørring plasseres etter = returnerer mer enn én rad, MySQL gir feil 1242, Delspørring returnerer mer enn én radBytt operatøren til IN, eller stramme inn den indre WHERE-klausulen.

2) Radunderspørring

A radunderspørring returnerer også en enkelt rad, men den raden kan inneholde mer enn én kolonne. Den ytre spørringen sammenligner derfor en rad med verdier mot en radkonstruktør i stedet for mot en enkelt verdi.

SELECT full_names, contact_number FROM members
WHERE (membership_number, gender) = (SELECT membership_number, gender FROM members WHERE full_names = 'Janet Jones');

De tillatte operatorene er de samme sammenligningsoperatorene som er oppført ovenfor, brukt på hele raden samtidig.

3) Tabellunderspørring

A tabellunderspørring returnerer flere rader, og ofte flere kolonner, så den ytre spørringen må bruke en settoperator som IN, NOT IN, ANY, ALLeller EXISTS.

La oss si at du vil ha navn og telefonnumre til medlemmer som har leid en film og ennå ikke har returnert den, slik at du kan ringe dem opp for å gi dem en påminnelse. Du kan bruke en spørring som denne:

SELECT full_names, contact_number FROM members
WHERE membership_number IN (SELECT membership_number FROM movierentals WHERE return_date IS NULL);

MySQL Undersøk

La oss se hvordan denne spørringen fungerer.

MySQL Undersøk

I dette tilfellet returnerer den indre spørringen mer enn ett resultat, så listen over medlemsnumre sendes til IN operatoren, og alle samsvarende medlemmer returneres.

Nestende underspørringer flere nivåer dypt

Så langt har du sett to nivåer. En delspørring kan også inneholde en annen delspørring, som produserer en trippelnestet setning.

Anta at ledelsen ønsker å belønne det medlemmet som betaler best. Vi kan kjøre en spørring som denne:

SELECT full_names FROM members
WHERE membership_number = (SELECT membership_number FROM payments
    WHERE amount_paid = (SELECT MAX(amount_paid) FROM payments));

Den innerste spørringen finner den største betalingen, den midterste spørringen konverterer dette beløpet til et medlemsnummer, og den ytre spørringen konverterer medlemsnummeret til et navn. Spørringen ovenfor gir følgende resultat:

MySQL Undersøk

Slik bruker du delspørringer med INSERT, UPDATE og DELETE

Delspørringer er ikke begrenset til SELECT-setninger. Det samme mønsteret i parentes fungerer i datamodifikasjonssetninger, som gjør at et helt sett med rader kan endres i én omgang uten å opprette en midlertidig tabell.

INSERT med en delspørring. En delspørring kan levere radene som settes inn, som kopierer data fra én tabell til en annen. Kolonnelisten i SELECT må være på linje med kolonnelisten i INSERT.

INSERT INTO vip_members (membership_number, full_names)
SELECT membership_number, full_names FROM members
WHERE membership_number IN (SELECT membership_number FROM payments WHERE amount_paid > 5000);

OPPDATERING med en delspørring. Her bestemmer den interne spørringen hvilke rader som berøres. Eksemplet nedenfor markerer alle medlemmer hvis utleie fortsatt er utestående.

UPDATE members
SET reminder_sent = 1
WHERE membership_number IN (SELECT membership_number FROM movierentals WHERE return_date IS NULL);

SLETT med en delspørring. Den samme ideen fjerner rader som oppfyller en betingelse i en andre tabell.

DELETE FROM members
WHERE membership_number NOT IN (SELECT membership_number FROM movierentals);

⚠️ Advarsel: MySQL tillater ikke at en setning endrer en tabell og velger fra den samme tabellen i en delspørring i FROM-klausulen. Hvis feil 1093 vises, pakk inn den indre spørringen i en avledet tabell, for eksempel SELECT * FROM (SELECT ...) AS t, Slik at MySQL materialiserer resultatet før endringen blir brukt. Det er også lurt å kjøre den indre SELECT-en på egenhånd først, og å bekrefte radantallet før du kjører en OPPDATERING eller SLETT i produksjon.

Underspørringer vs. sammenføyninger

Både en delspørring og en JOIN kan kombinere informasjon fra mer enn én tabell, så det naturlige spørsmålet er hvilken man skal gripe etter.

Sammenlignet med koblinger er underspørringer enkle å bruke og lettlese. De er ikke så kompliserte som tiltrer, og derfor brukes de ofte av SQL nybegynnere.

Men underspørringer har ytelsesproblemer. Å bruke en join i stedet for en underspørring kan noen ganger gi deg opptil 500 ganger bedre ytelse, fordi optimaliseringsprogrammet kan løse en join i én omgang i stedet for å evaluere den indre setningen gjentatte ganger.

Sammenligningspunkt Undersøk BLI
lesbarhet Høy, ettersom hver blokk svarer på ett spørsmål Lavere, ettersom alle tabellene vises i én klausul
Ytelse Tregere, den indre spørringen kan kjøre for hver ytre rad Raskere, ofte med en veldig stor margin
Resultatkolonner Bare kolonner i den ytre tabellen returneres Kolonner fra alle sammenkoblede tabeller kan returneres
Typisk bruk Filtrering på en verdi som må beregnes først Kombinere relaterte rader fra to eller flere tabeller
Læringskurve Mild, kjent for nybegynnere Brattere, krever kunnskap om sammenføyningstyper

Gitt et valg, anbefales det å bruke en JOIN over en underspørring. Underspørringer bør bare brukes som en reserveløsning når du ikke kan bruke en JOIN-operasjon for å oppnå det ovennevnte.

Undersøk vs sammenføyninger

Delspørringer er også enkle å dele opp i enkeltstående logiske komponenter, noe som er veldig nyttig når testing og feilsøking av spørringene.

Spørsmål og svar

En korrelert delspørring refererer til en kolonne i den ytre spørringen, så den evalueres én gang for hver ytre rad. En ikke-korrelert delspørring er uavhengig og kjører bare én gang. Korrelerte delspørringer er kraftige, men merkbart tregere på store tabeller.

En delspørring kan plasseres i WHERE-klausulen, HAVING-klausulen, SELECT-listen eller FROM-klausulen, hvor den blir en avledet tabell og krever et alias. Den er også gyldig i INSERT-, UPDATE- og DELETE-setninger.

Ofte, ja. AI-assistenter innebygd i redigeringsprogrammer som MySQL Workbench kan foreslå en tilsvarende BLISammenlign alltid radantall og les EXPLAIN-planen før du stoler på omskrivingen, fordi NULL-håndteringen kan variere.

Ja. Tekst til SQL-assistenter gjør om et spørsmål som «hvilken kategori har færrest filmer» til en nestet SELECT. Nøyaktigheten avhenger av skjemaet som er levert til modellen, så sjekk den genererte setningen mot de faktiske tabellnavnene.

Feilen oppstår når en delspørring plassert etter en sammenligningsoperator returnerer flere rader. Erstatt operatoren med IN, ANY eller EXISTS, eller stram den indre WHERE-klausulen slik at bare én rad returneres.

Oppsummer dette innlegget med: