- 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 aANY
vagyALL
. - 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
ésIN
aSELECT *
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
ésHAVING
záradékokat. - A
DISTINCT
kulcsszó nem használható olyan allekérdezéseknél, amelyek tartalmazzák a GROUP BY-t. - A
COMPUTE
ésINTO
záradékokat nem lehet megadni. -
ORDER BY
csak akkor adható meg, ha aTOP
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. AEXISTS
kóddal bevezetett részlekérdezés szabályai megegyeznek a szokásos kiválasztási lista szabályaival, mert aEXISTS
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.