allekérdezések (SQL Server)

  • 2018.02.18.
  • 21 perc olvasási idő
    • W
    • M
    • T
    • M
    • j
    • +3

A következőre vonatkozik: SQL Server (az összes támogatott verzió) Azure SQL Database Azure SQL kezelt példány Azure Synapse Analytics Párhuzamos adattárház

Az allekérdezés olyan lekérdezés, amely egy SELECT, INSERT, UPDATE vagy DELETE utasítás, vagy egy másik részlekérdezés belsejében. Allekérdezés bárhol használható, ahol egy kifejezés megengedett. Ebben a példában egy allekérdezést használunk egy MaxUnitPrice nevű oszlopkifejezésként egy SELECT utasításban.

Allekérdezés alapjai

Egy allekérdezés is belső lekérdezésnek vagy belső választásnak hívják, míg az allekérdezést tartalmazó utasítást külső lekérdezésnek vagy külső választásnak is hívják.

Sok olyan alkufuttatást tartalmazó Transact-SQL utasítás alternatívaként is megfogalmazható összekapcsolásként. Egyéb kérdéseket csak alkérdezésekkel lehet feltenni. A Transact-SQL rendszerben általában nincs teljesítménykülönbség egy allekérdezést tartalmazó utasítás és egy szemantikailag egyenértékű változat között, amely nem. Egyes esetekben azonban, ha ellenőrizni kell a létezést, a csatlakozás jobb teljesítményt nyújt. Ellenkező esetben a beágyazott lekérdezést a külső lekérdezés minden egyes eredményéhez fel kell dolgozni a duplikátumok kiküszöbölése érdekében. Ilyen esetekben a csatlakozási megközelítés jobb eredményeket hozna. Az alábbiakban bemutatunk egy példát SELECT és egy SELECT allekérdezésre, amelyek ugyanazt az eredménykészletet adják vissza:

A külső SELECT utasításba beágyazott allekérdezés a következő összetevőket tartalmazza:

  • Rendszeres SELECT lekérdezés beleértve a szokásos select list komponenseket.
  • Egy szabályos FROM záradék, amely egy vagy több tábla vagy nézet nevet tartalmaz.
  • Opcionális WHERE záradék.
  • Opcionális GROUP BY záradék.
  • Választható HAVING záradék.

Az allekérdezés SELECT lekérdezése mindig zárójelbe van zárva. Nem tartalmazhat COMPUTE vagy FOR BROWSE záradékot, és csak ORDER BY záradékot tartalmazhat, ha egy TOP záradék is meg van adva.

Egy részlekérdezés beágyazható egy külső rész WHERE vagy HAVING záradékába. SELECT, INSERT, UPDATE vagy DELETE utasítás, vagy egy másik allekérdezésen belül. Legfeljebb 32 fészkelési szint lehetséges, bár a korlát a rendelkezésre álló memória és a lekérdezés egyéb kifejezéseinek összetettsége alapján változik. Az egyes lekérdezések nem támogatják a beágyazást 32 szintig. Allekérdezés bárhol megjelenhet, ha egy kifejezés felhasználható, ha egyetlen értéket ad vissza.

Ha egy táblázat csak egy allekérdezésben jelenik meg, a külső lekérdezésben nem, akkor a táblázat oszlopai nem szerepelhetnek a output (a külső lekérdezés kiválasztási listája).

Az allekérdezést tartalmazó utasítások általában a következő formátumok egyikét ölelik fel:

  • WHERE kifejezés IN (subquery)
  • WHERE expression_operator (subquery) kifejezés
  • WHERE EXISTS (subquery)

Egyes Transact-SQL utasításokban az allekérdezés úgy értékelhető, mintha független lenne lekérdezés. Fogalmilag az allekérdezés eredményeit a külső lekérdezés helyettesíti (bár az SQL Server nem feltétlenül így dolgozza fel a Transact-SQL utasításokat alkérdezésekkel).

Három alapvető típusú lekérdezés létezik. Azok, amelyek:

  • Működnek a IN névvel bevezetett listákon, vagy azok, amelyeket egy összehasonlító operátor módosított a ANY vagy ALL.
  • Módosítatlan összehasonlító operátorral kerülnek bevezetésre, és egyetlen értéket kell megadniuk.
  • A EXISTS.

Allekérdezési szabályok

Az allekérdezésre a következő korlátozások vonatkoznak:

  • Az összehasonlító operátorral bevezetett részlekérdezés kiválasztási listája csak egy kifejezést vagy oszlopnevet tartalmazhat (kivéve, hogy EXISTS és IN a SELECT * vagy egy lista).
  • Ha egy külső lekérdezés WHERE záradékában oszlopnév szerepel, akkor csatlakozásnak kompatibilisnek kell lennie az allekérdezés-választási lista oszlopával.
  • Az ntext, a szöveg és a kép adattípusai nem használhatók az al lekérdezések kiválasztott listáján.
  • Mivel egyetlen értéket kell adniuk, a módosítatlan összehasonlító operátor (egy nem követi az ANY vagy ALL kulcsszó) nem tartalmazhatnak GROUP BY és HAVING záradékokat.
  • A DISTINCT kulcsszó nem használható olyan allekérdezéseknél, amelyek tartalmazzák a GROUP BY-t.
  • A COMPUTE és INTO záradékokat nem lehet megadni.
  • ORDER BY csak akkor adható meg, ha a TOP is meg van adva.
  • Az allekérdezés használatával létrehozott nézetet nem lehet frissíteni.
  • A EXISTS paranccsal bevezetett allekérdezés kiválasztási listája csillaggal ( *) egyetlen oszlopnév helyett. A EXISTS kóddal bevezetett részlekérdezés szabályai megegyeznek a szokásos kiválasztási lista szabályaival, mert a EXISTS kóddal bevezetett részlekérdezés létet hoz létre tesztel, és az IGAZ vagy HAMIS értéket adja vissza az adatok helyett.

Oszlopnevek minősítése allekérdezésekben

A következő példában a BusinessEntityID oszlop a záradékát implicit módon a tábla neve határozza meg a külső lekérdezés FROM záradékában (Sales.Store). Az allekérdezés kiválasztási listájában a CustomerID-re történő hivatkozást az FROM alkérdezés, vagyis a Sales.Customer tábla igazolja.

Általános szabály, hogy egy utasítás oszlopneveit implicit módon minősíti a FROM záradékban hivatkozott táblázat ugyanazon a szinten. Ha egy oszlop nem létezik az allekérdezés FROM záradékában hivatkozott táblázatban, akkor azt implicit módon a FROM a külső lekérdezés záradéka.

Így néz ki a lekérdezés a megadott implicit feltételezések mellett:

Soha nem baj a tábla nevének kifejezett megadásához, és mindig felül lehet írni a explicit minősítéssel rendelkező táblák nevével kapcsolatos implicit feltételezéseket.

Fontos

Ha egy oszlopra hivatkozunk egy olyan allekérdezésben, amely nem létezik az “s FROM záradék által hivatkozott táblázatban, de létezik egy olyan táblában, amelyre az” s FROM külső lekérdezés hivatkozik záradék, a lekérdezés hiba nélkül hajt végre. Az SQL Server implicit módon minősíti az allekérdezés oszlopát a táblanévvel a külső lekérdezésben.

Több fészkelési szint

Az allekérdezés magában foglalhat egy vagy több alkérdést. Bármely számú lekérdezés beágyazható egy utasításba.

A következő lekérdezés megtalálja azon alkalmazottak nevét, akik értékesítési személyek is.

Itt található az eredménykészlet.

A legbelső lekérdezés az eladó személyazonosítóit adja vissza. A következő magasabb szintű lekérdezést ezekkel az értékesítői személyazonosítókkal értékelik ki, és az alkalmazottak kapcsolattartási azonosítójait adja vissza. Végül a külső lekérdezés a kapcsolattartók azonosítóit használja az alkalmazottak nevének megkeresésére.

Ezt a lekérdezést csatlakozásként is kifejezheti:

Számos lekérdezést ki lehet értékelni úgy, hogy egyszer végrehajtja az alkérdezést, és a kapott értéket vagy értékeket a külső lekérdezés WHERE záradékával helyettesíti. Lekérdezésekben, amelyek összefüggő alkérdezést (más néven ismétlődő lekérdezést is tartalmaznak), az allekérdezés értéke a külső lekérdezéstől függ. Ez azt jelenti, hogy az allekérdezést többször hajtják végre, minden egyes sornál, amelyet a külső lekérdezés választhat ki. Ez a lekérdezés beolvassa az egyes alkalmazottak első és vezetéknevének egy példányát, amelyre a bónusz a SalesPerson táblában 5000, és amelyre a a munkavállalói azonosító számok megegyeznek az Employee és a SalesPerson táblákban.

Itt található az eredménykészlet.

A nyilatkozat előző lekérdezése nem értékelhető a külső lekérdezéstől függetlenül. Értékre van szüksége az Employee.BusinessEntityID számára, de ez az érték változik, mivel az SQL Server az Employee különböző sorait vizsgálja.
Ez pontosan így történik A lekérdezés kiértékelésre kerül: Az SQL Server úgy véli, hogy az Employee tábla minden sora felveszi az eredményeket azáltal, hogy az egyes sorok értékét behelyettesíti a belső lekérdezésbe. Például, ha az SQL Server először megvizsgálja a Syed Abbas, az Employee.BusinessEntityID változó a 285 értéket veszi fel, amelyet az SQL Server helyettesít bekerül a belső lekérdezésbe.

Az eredmény 0 (Syed Abbas nem kapott bónuszt, mert ő nem értékesítő), ezért a külső lekérdezés a következőket értékeli:

Mivel ez hamis, a Syed Abbas nem szerepel az eredmények között.

Write a Comment

Az email címet nem tesszük közzé. A kötelező mezőket * karakterrel jelöltük