Jegyzet
Az oldalhoz való hozzáférés engedélyezést igényel. Próbálhatod be jelentkezni vagy könyvtárat váltani.
Az oldalhoz való hozzáférés engedélyezést igényel. Megpróbálhatod a könyvtár váltását.
Vonatkozik a következőkre:SQL Server
Azure SQL Database
Azure SQL Managed Instance
Azure Synapse Analytics
Analitikai Platform System (PDW)
SQL adatbázis a Microsoft Fabric-ben
Az albekérdezések olyan lekérdezések, amelyek egy SELECT, INSERT, , UPDATEvagy DELETE utasításba vagy egy másik részkikérdezésbe vannak ágyazva.
A cikkben szereplő kódminták a AdventureWorks2025 vagy AdventureWorksDW2025 mintaadatbázist használják, amelyet a Microsoft SQL Server-minták és közösségi projektek kezdőlapjáról tölthet le.
Az alkérdezéseket bárhol használhatja, ahol egy kifejezés engedélyezve van. Ebben a példában egy subqueryt használunk egy MaxUnitPrice nevű oszlopkifejezésként egy SELECT utasításban.
USE AdventureWorks2022;
GO
SELECT Ord.SalesOrderID, Ord.OrderDate,
(SELECT MAX(OrdDet.UnitPrice)
FROM Sales.SalesOrderDetail AS OrdDet
WHERE Ord.SalesOrderID = OrdDet.SalesOrderID) AS MaxUnitPrice
FROM Sales.SalesOrderHeader AS Ord;
GO
A subquery alapjai
Az al lekérdezéseket belső lekérdezésnek vagy belső kijelölésnek is nevezik, míg az al lekérdezést tartalmazó utasítást külső lekérdezésnek vagy külső kijelölésnek is nevezik.
Számos Transact-SQL albekérdezéseket tartalmazó utasítást is lehet illesztésként megfogalmazni. Egyéb kérdéseket csak albekérdezésekkel lehet feltenni. A Transact-SQL-ben általában nincs teljesítménybeli különbség egy olyan utasítás között, amely tartalmaz egy al lekérdezést és egy szemantikailag egyenértékű verziót, amely nem. Az SQL Server lekérdezések feldolgozásának módjáról az SQL-utasítások feldolgozását ismertető cikkben olvashat. Bizonyos esetekben azonban, amikor a létezést ellenőrizni kell, az illesztés jobb teljesítményt eredményez. Ellenkező esetben a beágyazott lekérdezést a külső lekérdezés minden egyes eredményéhez fel kell dolgozni, hogy az ismétlődések kiküszöbölhetők legyenek. Ilyen esetekben az összekapcsolás módszere jobb eredményeket adna.
Az alábbi példában egy albekérdezés SELECT és egy illesztés SELECT látható, amely ugyanazt az eredményhalmazt és végrehajtási tervet adja vissza:
USE AdventureWorks2022;
GO
/* SELECT statement built using a subquery. */
SELECT [Name]
FROM Production.Product
WHERE ListPrice =
(SELECT ListPrice
FROM Production.Product
WHERE [Name] = 'Chainring Bolts' );
GO
/* SELECT statement built using a join that returns
the same result set. */
SELECT Prd1.[Name]
FROM Production.Product AS Prd1
JOIN Production.Product AS Prd2
ON (Prd1.ListPrice = Prd2.ListPrice)
WHERE Prd2.[Name] = 'Chainring Bolts';
GO
A külső SELECT utasításba beágyazott al lekérdezések a következő összetevőkkel rendelkezik:
- Egy szokásos
SELECTlekérdezés, beleértve a kiválasztási lista elemeit. - Egy reguláris
FROMzáradék, amely egy vagy több tábla- vagy nézetnevet tartalmaz. - Nem kötelező
WHEREzáradék. - Nem kötelező
GROUP BYzáradék. - Nem kötelező
HAVINGzáradék.
Az SELECT alkérdezések lekérdezése mindig zárójelben van. Nem tartalmazhat záradékot vagy záradékotCOMPUTE, és csak akkor tartalmazhat záradékotFOR BROWSE, ha egy ORDER BY záradék is meg van TOP adva.
Az albekérdezés beágyazható a WHERE vagy HAVING, SELECT, INSERT, vagy UPDATE utasítás egy külső záradékában, vagy egy másik albekérdezés záradékában. A beágyazás legfeljebb 32 szintig 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 legfeljebb 32 szint beágyazását támogatják. Ha az alkérdés egyetlen értéket ad vissza, akkor egy kifejezés bárhol használható, ahol felhasználható.
Ha egy tábla csak egy al lekérdezésben jelenik meg, a külső lekérdezésben nem, akkor a tábla oszlopai nem vehetők fel a kimenetbe (a külső lekérdezés kiválasztási listájába).
Az alkérdezéseket tartalmazó utasítások általában az alábbi formátumok egyikét használják:
WHERE expression [NOT] IN (subquery)WHERE expression comparison_operator [ANY | ALL] (subquery)WHERE [NOT] EXISTS (subquery)
Egyes Transact-SQL utasításokban az alkettő úgy értékelhető ki, mintha független lekérdezés lenne. Elméletileg az al lekérdezési eredmények a külső lekérdezésbe lesznek helyettesítve (bár az SQL Server nem feltétlenül így dolgozza fel Transact-SQL utasításokat az al lekérdezésekkel).
Három alapvető típusú lekérdezés létezik. Azok, amelyek:
- Listaelemekkel dolgozzon, amelyeket
INvezettek be, vagy amelyeket összehasonlító operátor módosítottANYvagyALL. - A rendszer nem módosított összehasonlító operátorral van bevezetve, és egyetlen értéket kell visszaadnia.
- A létezési teszteket a
EXISTS-vel vezették be.
Subquery-szabályok
Az al lekérdezésekre a következő korlátozások vonatkoznak:
- Az összehasonlító operátorral bevezetett allekérdezés kiválasztási listája csak egy kifejezést vagy oszlopnevet tartalmazhat, kivéve ha
EXISTSésINaSELECT *-n vagy egy listán működik, illetve. - Ha egy
WHEREkülső lekérdezés záradéka tartalmaz egy oszlopnevet, akkor az összeilleszthetőnek kell lennie az al lekérdezésválasztó listában szereplő oszlopmal. - Az ntext, text és image adattípusok nem használhatók az al-lekérdezések lekérdezési listáján.
- Mivel egyetlen értéket kell visszaadniuk, a nem módosított összehasonlító operátor által bevezetett alkérdezések (amelyeket nem követ a kulcsszó
ANYvagyALL) nem tartalmazhatnakGROUP BYésHAVINGzáradékokat. - A
DISTINCTkulcsszó nem használható olyan al lekérdezésekkel, amelyek tartalmazzák a következőtGROUP BY: . - A
COMPUTEésINTOzáradékok nem adhatók meg. -
ORDER BYcsak akkor adható meg, haTOPaz is meg van adva. - Az al-lekérdezéssel létrehozott nézet nem frissíthető.
- A konvenciók szerint bevezetett
EXISTSalkérdés lista esetén egyetlen oszlopnév helyett csillagot (*) használ. AEXISTS-vel bevezetett al lekérdezésekre vonatkozó szabályok megegyeznek a normál választólista szabályaival, mivel aEXISTS-vel bevezetett al lekérdezés egy létezési tesztet hoz létre, és az adatok helyett IGAZ vagy HAMIS értéket ad vissza.
Oszlopnevek minősítése az al lekérdezésekben
Az alábbi példában a BusinessEntityID külső lekérdezés záradékában szereplő WHERE oszlopot implicit módon a külső lekérdezési FROM záradékban (Sales.Store) szereplő táblanév minősíti. A részkérdés kiválasztási listájában szereplő CustomerID hivatkozást a részkérdés FROM záradéka minősíti, nevezetesen a Sales.Customer tábla.
USE AdventureWorks2022;
GO
SELECT [Name]
FROM Sales.Store
WHERE BusinessEntityID NOT IN
(SELECT CustomerID
FROM Sales.Customer
WHERE TerritoryID = 5);
GO
Az általános szabály az, hogy az utasításban szereplő oszlopneveket implicit módon minősíti a FROM záradékban hivatkozott tábla ugyanazon a szinten. Ha egy oszlop nem létezik egy al lekérdezés záradékában hivatkozott táblában FROM , azt implicit módon minősíti a külső lekérdezés záradékában FROM hivatkozott tábla.
A lekérdezés így néz ki a megadott implicit feltételezésekkel:
USE AdventureWorks2022;
GO
SELECT [Name]
FROM Sales.Store
WHERE Sales.Store.BusinessEntityID NOT IN
(SELECT Sales.Customer.CustomerID
FROM Sales.Customer
WHERE TerritoryID = 5);
GO
Soha nem baj, ha explicit módon adja meg a tábla nevét, és mindig lehetséges felülbírálni az explicit minősítéssel rendelkező táblanevek implicit feltételezéseit.
Important
Ha egy olyan al lekérdezésben hivatkozik egy oszlopra, amely nem szerepel az alquery FROM záradéka által hivatkozott táblában, de a külső lekérdezés záradéka FROM által hivatkozott táblában létezik, a lekérdezés hiba nélkül fut. Az SQL Server implicit módon minősíti az al lekérdezés oszlopát a külső lekérdezés táblanevével.
Többszintű beágyazás
Az albekérdezések maguk is tartalmazhatnak egy vagy több albekérdezőt. Tetszőleges számú albekérdezés beágyazható egy utasításba.
Az alábbi lekérdezés megkeresi azon alkalmazottak nevét, akik szintén értékesítők.
USE AdventureWorks2022;
GO
SELECT LastName, FirstName
FROM Person.Person
WHERE BusinessEntityID IN
(SELECT BusinessEntityID
FROM HumanResources.Employee
WHERE BusinessEntityID IN
(SELECT BusinessEntityID
FROM Sales.SalesPerson)
);
GO
Itt van az eredmények összessége.
LastName FirstName
-------------------------------------------------- -----------------------
Jiang Stephen
Abbas Syed
Alberts Amy
Ansman-Wolfe Pamela
Campbell David
Carson Jillian
Ito Shu
Mitchell Linda
Reiter Tsvi
Saraiva Jos
Vargas Garrett
Varkey Chudukatil Ranjit
Valdez Rachel
Tsoflias Lynn
Pak Jae
Blythe Michael
Mensa-Annan Tete
(17 row(s) affected)
A legbelső lekérdezés az értékesítési személy azonosítóit adja vissza. A következő magasabb szintű lekérdezés kiértékelése az értékesítési személy azonosítóival történik, és visszaadja az alkalmazottak kapcsolattartási azonosítószámát. Végül a külső lekérdezés a kapcsolat azonosítókat használja az alkalmazottak nevének megkeresésére.
A lekérdezést összekapcsolásként is kifejezheti:
USE AdventureWorks2022;
GO
SELECT LastName, FirstName
FROM Person.Person c
INNER JOIN HumanResources.Employee e
ON c.BusinessEntityID = e.BusinessEntityID
JOIN Sales.SalesPerson s
ON e.BusinessEntityID = s.BusinessEntityID;
GO
Korrelált al lekérdezések
Számos lekérdezés kiértékelhető úgy, hogy egyszer végrehajtja az al lekérdezést, és az eredményül kapott értéket vagy értékeket a WHERE külső lekérdezés záradékába helyettesíti. A korrelált részqueryt (más néven ismétlődő részqueryt) tartalmazó lekérdezésekben az al lekérdezés az értékei külső lekérdezésétől függ. Ez azt jelenti, hogy az allekérdezés ismétlődően lesz végrehajtva minden olyan sorhoz, amelyet a külső lekérdezés kiválaszthat.
Ez a lekérdezés lekéri az egyes alkalmazottak vezeték- és utónevének egy példányát, amelyeknek a bónusza az SalesPerson táblában 5000, és amelyeknél az alkalmazott-azonosító számok megegyeznek a Employee és a SalesPerson táblákban.
USE AdventureWorks2022;
GO
SELECT DISTINCT c.LastName, c.FirstName, e.BusinessEntityID
FROM Person.Person AS c JOIN HumanResources.Employee AS e
ON e.BusinessEntityID = c.BusinessEntityID
WHERE 5000.00 IN
(SELECT Bonus
FROM Sales.SalesPerson sp
WHERE e.BusinessEntityID = sp.BusinessEntityID) ;
GO
Itt van az eredmények összessége.
LastName FirstName BusinessEntityID
-------------------------- ---------- ------------
Ansman-Wolfe Pamela 280
Saraiva José 282
(2 row(s) affected)
A korábbi részkérdés ebben az utasításban önállóan nem értékelhető ki a külső lekérkezéstől függetlenül. Szüksége van egy értékreEmployee.BusinessEntityID, de ez az érték megváltozik, amikor az SQL Server megvizsgálja a különböző sorokat.Employee
A lekérdezés kiértékelése pontosan így történik: Az SQL Server a tábla minden sorát figyelembe veszi az Employee eredményekbe való felvételhez, ha az egyes sorokban lévő értéket a belső lekérdezésbe helyettesíti.
Ha például az SQL Server először megvizsgálja a sort Syed Abbas, a változó Employee.BusinessEntityID azt az értéket 285veszi fel, amelyet az SQL Server helyettesít a belső lekérdezésben. Ez a két lekérdezésminta az előző minta és a korrelált részkikérdezés felbontását jelöli.
USE AdventureWorks2022;
GO
SELECT Bonus
FROM Sales.SalesPerson
WHERE BusinessEntityID = 285;
GO
Az eredmény 0,00 (Syed Abbas nem kapott bónuszt, mert nem értékesítő), ezért a külső lekérdezés a következőre értékel:
USE AdventureWorks2022;
GO
SELECT LastName, FirstName
FROM Person.Person AS c JOIN HumanResources.Employee AS e
ON e.BusinessEntityID = c.BusinessEntityID
WHERE 5000 IN (0.00);
GO
Mivel ez hamis, a sor Syed Abbas nem szerepel az előző minta lekérdezés eredményei között a korrelált részkikérdezéssel. Kövesse ugyanazt az eljárást a Pamela Ansman-Wolfe sor esetében. Láthatja, hogy ez a sor szerepel az eredmények között, mert WHERE 5000 IN (5000) az eredményeket is tartalmazza.
A korrelált al lekérdezések a záradékban FROM táblaértékkel rendelkező függvényeket is tartalmazhatnak, ha a külső lekérdezés egyik táblájának oszlopaira hivatkoznak a táblaértékelő függvény argumentumaként. Ebben az esetben a külső lekérdezés minden sora esetében a táblaértékelt függvény kiértékelése az alkérdezés alapján történik.
Subquery-típusok
Az albekérdezések számos helyen megadhatóak:
- Aliasokkal. További információ: Táblázat aliasokkal rendelkező albekérdezések.
-
IN-val vagyNOT IN-val. További információ: Allekérdezések az IN feltétellel és Allekérdezések a NEM IN feltétellel. - In
UPDATE,DELETE, ésINSERTutasításokban. További információkért lásd az UPDATE, DELETE és INSERT utasításokban szereplő részkikérdezéseket. - Összehasonlító operátorokkal. További információkért tekintse meg az összehasonlító operátorokkal rendelkező allekérdezéseket.
- A
ANY,SOMEvagyALL. További információkért tekintse meg az ANY, a SOME vagy az ALL által módosított összehasonlító operátorokat. - Val
IS [NOT] DISTINCT FROM. További információért lásd: IS [NOT] DISTINCT FROM (Transact-SQL). -
EXISTS-val vagyNOT EXISTS-val. További információkért tekintse meg a EXISTS és a NOT EXISTS albekérdezéseket. - Kifejezés helyett. További információ: Kifejezés helyett használt al lekérdezések.
Táblaaliasokkal rendelkező albekérdezések
Számos olyan utasítás, amelyben az al lekérdezés és a külső lekérdezés ugyanarra a táblára hivatkozik, önillesztésként (egy táblázat önmagához illesztve) is megadható. Egy adott állam alkalmazottainak címei például egy allekérdezéssel találhatók meg.
USE AdventureWorks2022;
GO
SELECT StateProvinceID, AddressID
FROM Person.Address
WHERE AddressID IN
(SELECT AddressID
FROM Person.Address
WHERE StateProvinceID = 39);
GO
Itt van az eredmények összessége.
StateProvinceID AddressID
----------- -----------
39 942
39 955
39 972
39 22660
(4 row(s) affected)
Vagy használhat önillesztéseket is:
USE AdventureWorks2022;
GO
SELECT e1.StateProvinceID, e1.AddressID
FROM Person.Address AS e1
INNER JOIN Person.Address AS e2
ON e1.AddressID = e2.AddressID
AND e2.StateProvinceID = 39;
GO
A tábla aliasai e1e2 kötelezőek, mert az összekapcsolt tábla két különböző szerepkörben jelenik meg. Az aliasok olyan beágyazott lekérdezésekben is használhatók, amelyek ugyanarra a táblára hivatkoznak egy belső és külső lekérdezésben.
USE AdventureWorks2022;
GO
SELECT e1.StateProvinceID, e1.AddressID
FROM Person.Address AS e1
WHERE e1.AddressID IN
(SELECT e2.AddressID
FROM Person.Address AS e2
WHERE e2.StateProvinceID = 39);
GO
Az explicit táblaaliasok egyértelművé teszik, hogy az allekérdezésben szereplő Person.Address hivatkozás nem ugyanazt jelenti, mint a külső lekérdezésben szereplő hivatkozás.
Alférlekérdezések az IN használatával
A IN (vagy NOT IN) használatával bevezetett lekérdezés eredménye egy nulla vagy több értéket tartalmazó lista. Miután az alkérdezés eredményeket ad vissza, a külső lekérdezés felhasználja őket.
Az alábbi lekérdezés megkeresi az Adventure Works Cycles által előállított összes keréktermék nevét.
USE AdventureWorks2022;
GO
SELECT [Name]
FROM Production.Product
WHERE ProductSubcategoryID IN
(SELECT ProductSubcategoryID
FROM Production.ProductSubcategory
WHERE [Name] = 'Wheels');
GO
Itt van az eredmények összessége.
Name
----------------------------
LL Mountain Front Wheel
ML Mountain Front Wheel
HL Mountain Front Wheel
LL Road Front Wheel
ML Road Front Wheel
HL Road Front Wheel
Touring Front Wheel
LL Mountain Rear Wheel
ML Mountain Rear Wheel
HL Mountain Rear Wheel
LL Road Rear Wheel
ML Road Rear Wheel
HL Road Rear Wheel
Touring Rear Wheel
(14 row(s) affected)
Ezt a kijelentést két lépésben értékeljük. Először is a belső lekérdezés a névnek Wheel (17) megfelelő alkategóriás azonosítószámot adja vissza. Másodszor, ez az érték a külső lekérdezésbe kerül, amely megkeresi azokat a termékneveket, amelyek az alkategória-azonosító számokkal együtt szerepelnek a következőben Production.Product: .
USE AdventureWorks2022;
GO
SELECT [Name]
FROM Production.Product
WHERE ProductSubcategoryID IN ('17');
GO
Ehhez és hasonló problémákhoz való illesztés és nem allekérdezés használatának egyik előnye, hogy az illesztés lehetővé teszi több tábla oszlopainak megjelenítését az eredményben. Ha például meg szeretné adni a termék alkategóriájának nevét az eredményben, illesztési verziót kell használnia.
USE AdventureWorks2022;
GO
SELECT p.[Name], s.[Name]
FROM Production.Product p
INNER JOIN Production.ProductSubcategory s
ON p.ProductSubcategoryID = s.ProductSubcategoryID
AND s.[Name] = 'Wheels';
GO
Itt van az eredmények összessége.
Name
LL Mountain Front Wheel Wheels
ML Mountain Front Wheel Wheels
HL Mountain Front Wheel Wheels
LL Road Front Wheel Wheels
ML Road Front Wheel Wheels
HL Road Front Wheel Wheels
Touring Front Wheel Wheels
LL Mountain Rear Wheel Wheels
ML Mountain Rear Wheel Wheels
HL Mountain Rear Wheel Wheels
LL Road Rear Wheel Wheels
ML Road Rear Wheel Wheels
HL Road Rear Wheel Wheels
Touring Rear Wheel Wheels
(14 row(s) affected)
Az alábbi lekérdezés megkeresi azoknak a szállítóknak a nevét, akiknek a hitelképessége jó, akiktől az Adventure Works Cycles legalább 20 tételt rendel, és akiknek az átlagos átfutási ideje kevesebb, mint 16 nap.
USE AdventureWorks2022;
GO
SELECT [Name]
FROM Purchasing.Vendor
WHERE CreditRating = 1
AND BusinessEntityID IN
(SELECT BusinessEntityID
FROM Purchasing.ProductVendor
WHERE MinOrderQty >= 20
AND AverageLeadTime < 16);
GO
Itt van az eredmények összessége.
Name
--------------------------------------------------
Compete Enterprises, Inc
International Trek Center
First National Sport Co.
Comfort Road Bicycles
Circuit Cycles
First Rate Bicycles
Jeff's Sporting Goods
Competition Bike Training Systems
Electronic Bike Repair & Supplies
Crowley Sport
Expert Bike Co
Team Athletic Co.
Compete, Inc.
(13 row(s) affected)
A rendszer kiértékeli a belső lekérdezést, amely azoknak a szállítóknak az azonosítószámát generálja, akik megfelelnek az alkérési képesítéseknek. Ezután kiértékeli a külső lekérdezést. A belső és a WHERE külső lekérdezés záradékában több feltétel is szerepelhet.
Illesztés esetén ugyanez a lekérdezés a következőképpen fejeződik ki:
USE AdventureWorks2022;
GO
SELECT DISTINCT [Name]
FROM Purchasing.Vendor v
INNER JOIN Purchasing.ProductVendor p
ON v.BusinessEntityID = p.BusinessEntityID
WHERE CreditRating = 1
AND MinOrderQty >= 20
AND AverageLeadTime < 16;
GO
Az illesztés mindig kifejezhető részbekérdezésként. Az albekérdezéseket gyakran, de nem mindig lehet összekapcsolásként kifejezni. Ennek az az oka, hogy az illesztések szimmetrikusak: a táblázatot AB bármelyik sorrendbe illesztheti, és ugyanazt a választ kapja. Ugyanez nem igaz, ha egy alkérdéssel is foglalkozunk.
Lekérdezések a NOT IN használatával
A kulcsszóval NOT IN bevezetett albekérdezések nulla vagy több érték listáját is visszaadják.
Az alábbi lekérdezés megkeresi a nem kész kerékpárok termékeinek nevét.
USE AdventureWorks2022;
GO
SELECT [Name]
FROM Production.Product
WHERE ProductSubcategoryID NOT IN
(SELECT ProductSubcategoryID
FROM Production.ProductSubcategory
WHERE [Name] = 'Mountain Bikes'
OR [Name] = 'Road Bikes'
OR [Name] = 'Touring Bikes');
GO
Ez az utasítás nem konvertálható illesztéssé. Az analóg nem egyenlő illesztésnek más jelentése van: Megkeresi azoknak a termékeknek a nevét, amelyek bizonyos alkategóriákban találhatók, amelyek nem kész kerékpárok.
Az UPDATE, a DELETE és az INSERT utasítás albekérdezései
Az albekérdezések beágyazhatók a , UPDATE, DELETEés INSERT az SELECTadatmanipulációs (DML) utasításokba.
Az alábbi példa megduplázza a tábla oszlopának ListPriceProduction.Product értékét. A WHERE záradékban szereplő al-lekérdezés a Purchasing.ProductVendor táblára hivatkozik, így a Termék táblában frissített sorokat csak a BusinessEntity1540 megadott sorokra korlátozza.
USE AdventureWorks2022;
GO
UPDATE Production.Product
SET ListPrice = ListPrice * 2
WHERE ProductID IN
(SELECT ProductID
FROM Purchasing.ProductVendor
WHERE BusinessEntityID = 1540);
GO
Íme egy egyenértékű UPDATE utasítás illesztés használatával:
USE AdventureWorks2022;
GO
UPDATE Production.Product
SET ListPrice = ListPrice * 2
FROM Production.Product AS p
INNER JOIN Purchasing.ProductVendor AS pv
ON p.ProductID = pv.ProductID AND BusinessEntityID = 1540;
GO
Az érthetőség kedvéért, ha ugyanaz a tábla más allekérdezésekben is hivatkozásra kerül, használja a céltábla aliasát:
USE AdventureWorks2022;
GO
UPDATE p
SET ListPrice = ListPrice * 2
FROM Production.Product AS p
INNER JOIN Purchasing.ProductVendor AS pv
ON p.ProductID = pv.ProductID AND BusinessEntityID = 1540;
GO
Allekérdezések összehasonlító operátorokkal
Az allekérdezések az összehasonlító operátorok (=, , , < >>, > =, <, ! >, ! <, vagy < =) egyikével vezethetők be.
A módosítatlan összehasonlító operátorral (mint például az, amelyet nem követ ANY vagy ALL) bevezetett al-lekérdezéseknek egyetlen értéket kell visszaadniuk az értékek listája helyett, mint például az IN-vel bevezetett al-lekérdezéseknél. Ha egy ilyen al lekérdezés több értéket ad vissza, az SQL Server hibaüzenetet jelenít meg.
A változatlan összehasonlító operátorral bevezetett al-lekérdezés használatához elég jól kell ismernie az adatokat és a probléma természetét ahhoz, hogy tudja, hogy az al-lekérdezés pontosan egy értéket fog visszaadni.
Ha például feltételezi, hogy az egyes értékesítők csak egy értékesítési területet fednek le, és meg szeretné találni azokat az ügyfeleket, akik Linda Mitchell által lefedett területen helyezkednek el, akkor írhat egy olyan lekérdezést, amely az egyszerű = összehasonlító operátort használja egy allekérdezés bevezetésére.
USE AdventureWorks2022;
GO
SELECT CustomerID
FROM Sales.Customer
WHERE TerritoryID =
(SELECT TerritoryID
FROM Sales.SalesPerson
WHERE BusinessEntityID = 276);
GO
Ha azonban Linda Mitchell egynél több értékesítési területet fed le, hibaüzenet jelenik meg. Az = összehasonlító operátor helyett egy IN kifejezés használható (=ANY szintén működik).
A nem módosított összehasonlító operátorokkal bevezetett allekérdezések gyakran aggregátumfüggvényeket tartalmaznak, mivel ezek egyetlen értéket adnak vissza. Az alábbi utasítás például az összes olyan termék nevét keresi meg, amelynek listaára nagyobb, mint az átlagos listaár.
USE AdventureWorks2022;
GO
SELECT [Name]
FROM Production.Product
WHERE ListPrice >
(SELECT AVG (ListPrice)
FROM Production.Product);
GO
Mivel a módosítatlan összehasonlító operátorokkal bevezetett allekérdezéseknek egyetlen értéket kell visszaadniuk, csak akkor tartalmazhatnak GROUP BY vagy HAVING záradékokat, ha ön tudja, hogy maga a GROUP BYHAVING záradék egyetlen értéket ad vissza. Az alábbi lekérdezés például azokat a termékeket keresi meg, amelyek ProductSubcategoryID14ára magasabb, mint a legalacsonyabb árú termék.
USE AdventureWorks2022;
GO
SELECT [Name]
FROM Production.Product
WHERE ListPrice >
(SELECT MIN (ListPrice)
FROM Production.Product
GROUP BY ProductSubcategoryID
HAVING ProductSubcategoryID = 14);
GO
Összehasonlító operátorok, amelyeket módosítottak ANY, SOMEvagy ALL
Az összehasonlító operátorokkal bevezetett allekérdezések módosíthatók a ALL vagy ANY kulcsszavakkal.
SOME A ISO szabvány megfelelője ANY. További információ ezekről az összehasonlító operátorokról: SOME | BÁRMELYIK.
A módosított összehasonlító operátor használata esetén bevezetett al-lekérdezések nulla vagy több értékből álló listát adnak vissza, és tartalmazhatnak GROUP BY vagy HAVING záradékokat is. Ezek az al-lekérdezések újrafogalmazhatók a EXISTS.
> Az összehasonlító operátor példaként > ALL való használata minden értéknél nagyobbat jelent. Más szóval ez nagyobb értéket jelent, mint a maximális érték. Például > ALL (1, 2, 3) 3-nál nagyobb értéket jelent.
> ANY legalább egynél nagyobb értéket, azaz a minimumnál nagyobb értéket jelent. Tehát > ANY (1, 2, 3) 1-nél nagyobbat jelent.
A külső lekérdezésben megadott feltételnek megfelelő al lekérdezések > ALL soraiban az al lekérdezést bevezető oszlopban szereplő értéknek nagyobbnak kell lennie, mint az al lekérdezés által visszaadott értékek listájának minden egyes értéke.
Hasonlóképpen azt is jelenti, hogy ahhoz, > ANY hogy egy sor megfeleljen a külső lekérdezésben megadott feltételnek, az al lekérdezést beíró oszlopban lévő értéknek nagyobbnak kell lennie az al lekérdezés által visszaadott értékek listájában szereplő értékek legalább egyikénél.
Az alábbi lekérdezés példát mutat egy olyan alkérésre, amelyet ANY által módosított összehasonlító operátorral vezet be. Megkeresi azokat a termékeket, amelyek listaárai nagyobbak vagy egyenlők bármely termék alkategóriájának maximális listaárainál.
USE AdventureWorks2022;
GO
SELECT [Name]
FROM Production.Product
WHERE ListPrice >= ANY
(SELECT MAX (ListPrice)
FROM Production.Product
GROUP BY ProductSubcategoryID);
GO
Minden Termék alkategóriához a belső lekérdezés megkeresi a maximális listaárat. A külső lekérdezés mindezeket az értékeket megvizsgálja, és meghatározza, hogy az egyes termékek listaárai nagyobbak vagy egyenlőek-e bármely termék alkategóriájának maximális listaárainál. Ha ANY módosul ALL, a lekérdezés csak azokat a termékeket adja vissza, amelyek listaára nagyobb vagy egyenlő a belső lekérdezésben visszaadott listaárakkal.
Ha az al lekérdezés nem ad vissza értékeket, a teljes lekérdezés nem ad vissza értékeket.
Az = ANY operátor egyenértékű a IN. Ha például meg szeretné keresni az Adventure Works Cycles által előállított összes keréktermék nevét, használhatja vagy IN= ANY.
--Using = ANY
USE AdventureWorks2022;
GO
SELECT [Name]
FROM Production.Product
WHERE ProductSubcategoryID = ANY
(SELECT ProductSubcategoryID
FROM Production.ProductSubcategory
WHERE Name = 'Wheels');
GO
--Using IN
USE AdventureWorks2022;
GO
SELECT [Name]
FROM Production.Product
WHERE ProductSubcategoryID IN
(SELECT ProductSubcategoryID
FROM Production.ProductSubcategory
WHERE Name = 'Wheels');
GO
Az alábbi eredményhalmaz bármelyik lekérdezéshez használható:
Name
--------------------------------------------------
LL Mountain Front Wheel
ML Mountain Front Wheel
HL Mountain Front Wheel
LL Road Front Wheel
ML Road Front Wheel
HL Road Front Wheel
Touring Front Wheel
LL Mountain Rear Wheel
ML Mountain Rear Wheel
HL Mountain Rear Wheel
LL Road Rear Wheel
ML Road Rear Wheel
HL Road Rear Wheel
Touring Rear Wheel
(14 row(s) affected)
Az <> ANY operátor azonban eltér a következőtől NOT IN:
-
<> ANYnem egyenlő az a-val, vagy nem egyenlő a b-vel, vagy nem egyenlő a c-vel -
NOT INnem egyenlő a-val, vagy nem egyenlő b-vel, vagy nem egyenlő c-vel -
<> ALLugyanazt jelenti, mint aNOT IN
Az alábbi lekérdezés például olyan területen található ügyfeleket keres, amelyekre nem vonatkoznak értékesítők.
USE AdventureWorks2022;
GO
SELECT CustomerID
FROM Sales.Customer
WHERE TerritoryID <> ANY
(SELECT TerritoryID
FROM Sales.SalesPerson);
GO
Az eredmények az összes ügyfelet tartalmazzák, kivéve azokat, amelyek értékesítési területei vannak NULL, mivel az ügyfélhez rendelt összes területet egy értékesítő fedezi. A belső lekérdezés megkeresi az értékesítők által lefedett összes értékesítési területet, majd minden egyes területen a külső lekérdezés megkeresi azokat az ügyfeleket, akik nem egyben szerepelnek.
Ugyanezen okból, amikor ezt a lekérdezést használja NOT IN , az eredmények egyik ügyfelet sem tartalmazzák.
Ugyanezeket az eredményeket a <> ALL operátorral is megkaphatja, amely egyenértékű a NOT IN.
Albekérdezések a EXISTS
Ha egy al-lekérdezést a kulcsszóval EXISTS vezetnek be, az al-lekérdezés létezési tesztként működik. A WHERE külső lekérdezés záradéka ellenőrzi, hogy léteznek-e az al lekérdezés által visszaadott sorok. Az albekérdezés valójában nem hoz létre adatokat; egy vagy több értéket TRUEFALSEad vissza.
A bevezetett EXISTS al lekérdezések szintaxisa a következő: WHERE [NOT] EXISTS (subquery)
Az alábbi lekérdezés megkeresi a Wheels alkategóriába tartozó összes termék nevét:
USE AdventureWorks2022;
GO
SELECT [Name]
FROM Production.Product
WHERE EXISTS
(SELECT *
FROM Production.ProductSubcategory
WHERE ProductSubcategoryID =
Production.Product.ProductSubcategoryID
AND [Name] = 'Wheels');
GO
Itt van az eredmények összessége.
Name
--------------------------------------------------
LL Mountain Front Wheel
ML Mountain Front Wheel
HL Mountain Front Wheel
LL Road Front Wheel
ML Road Front Wheel
HL Road Front Wheel
Touring Front Wheel
LL Mountain Rear Wheel
ML Mountain Rear Wheel
HL Mountain Rear Wheel
LL Road Rear Wheel
ML Road Rear Wheel
HL Road Rear Wheel
Touring Rear Wheel
(14 row(s) affected)
A lekérdezés eredményeinek megértéséhez vegye figyelembe az egyes termékek nevét. Ez az érték okozza, hogy az alkérdezés legalább egy sort visszaad? Más szóval a lekérdezés a létezési teszt kiértékelését TRUE eredményezi?
A bevezetett EXISTS albekérdezések kissé eltérnek a többi albekérdezéstől az alábbi módokon:
- A kulcsszót
EXISTSnem előzi meg oszlopnév, állandó vagy egyéb kifejezés. - Szinte mindig csillagot (*) tartalmaz a
EXISTSáltal bevezetett részkikérdezés lekérdezési listája. Nincs szükség az oszlopnevek listázására, mert csak azt teszteljük, hogy léteznek-e olyan sorok, amelyek megfelelnek az al-lekérdezésben megadott feltételeknek.
A EXISTS kulcsszó azért fontos, mert gyakran nem létezik helyettesítő készítmény albekérdezések nélkül. Bár a EXISTS-val létrehozott lekérdezések egy része más módon nem fejezhető ki, sok lekérdezés elérheti a hasonló eredményeket IN, vagy olyan összehasonlító operátorral, amelyet ANY vagy ALL módosít.
Az előző lekérdezés például a következő használatával INfejezhető ki:
USE AdventureWorks2022;
GO
SELECT [Name]
FROM Production.Product
WHERE ProductSubcategoryID IN
(SELECT ProductSubcategoryID
FROM Production.ProductSubcategory
WHERE [Name] = 'Wheels');
GO
Albekérdezések a NOT EXISTS
NOT EXISTS úgy működik, mint EXISTS, kivéve, hogy a WHERE záradék akkor teljesül, ha az alkérdezés nem ad vissza sorokat.
Például a kerekek alkategóriájában nem szereplő termékek neveinek megkeresése:
USE AdventureWorks2022;
GO
SELECT [Name]
FROM Production.Product
WHERE NOT EXISTS
(SELECT *
FROM Production.ProductSubcategory
WHERE ProductSubcategoryID =
Production.Product.ProductSubcategoryID
AND [Name] = 'Wheels');
GO
Kifejezés helyett használt al lekérdezések
A Transact-SQL-ben egy al-lekérdezés bárhol helyettesíthető, ahol egy kifejezés használható a SELECT, UPDATE, INSERT és DELETE utasításokban, kivéve a ORDER BY lista esetét.
Az alábbi példa bemutatja, hogyan használhatja ezt a fejlesztést. Ez a lekérdezés az összes hegyikerékpár-termék árát, azok átlagárat, valamint az egyes hegyikerékpárok árai és az átlagos ár közötti különbséget találja.
USE AdventureWorks2022;
GO
SELECT [Name], ListPrice,
(SELECT AVG(ListPrice) FROM Production.Product) AS Average,
ListPrice - (SELECT AVG(ListPrice) FROM Production.Product)
AS Difference
FROM Production.Product
WHERE ProductSubcategoryID = 1;
GO
Kapcsolódó tartalom
- IN (Transact-SQL)
- EXISTS (Transact-SQL)
- ALL (Transact-SQL)
- NÉHÁNY | ANY (Transact-SQL)
- Illesztések (SQL Server)
- Összehasonlító operátorok (Transact-SQL)
- lekérdezésfeldolgozási architektúra útmutatója
- Legjobb gyakorlatok a számítási feladatok figyelésére a Lekérdezéstárral
- intelligens lekérdezésfeldolgozás SQL-adatbázisokban
- számosság becslése (SQL Server)