Not
Bu sayfaya erişim yetkilendirme gerektiriyor. Oturum açmayı veya dizinleri değiştirmeyi deneyebilirsiniz.
Bu sayfaya erişim yetkilendirme gerektiriyor. Dizinleri değiştirmeyi deneyebilirsiniz.
Şunlar için geçerlidir:SQL Server
Azure SQL Database
Azure SQL Managed Instance
Azure Synapse Analytics
Analitik Platform Sistemi (PDW)
Microsoft Fabric'te SQL veritabanı
Alt sorgu, bir , SELECT, INSERTveya deyiminin içine veya UPDATE başka bir alt sorguya iç içe yerleştirilmiş bir DELETEsorgudur.
Bu makaledeki kod örnekleri, AdventureWorks2025 giriş sayfasından indirebileceğiniz veya AdventureWorksDW2025 örnek veritabanını kullanır.
Alt sorgu, bir ifadeye izin verilen her yerde kullanılabilir. Bu örnekte, bir alt sorgu deyiminde MaxUnitPrice adlı bir SELECT sütun ifadesi olarak kullanılır.
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
Alt sorgu temelleri
Alt sorgu, iç sorgu veya iç seçim olarak da adlandırılırken, alt sorgu içeren deyim dış sorgu veya dış seçim olarak da adlandırılır.
Alt sorgular içeren birçok Transact-SQL deyimi alternatif olarak birleşim olarak formüle edilebilir. Diğer sorular yalnızca alt sorgularla sorulabilir. Transact-SQL'de, alt sorgu içeren bir deyimle olmayan sematik olarak eşdeğer bir sürüm arasında genellikle performans farkı yoktur. SQL Server'ın sorguları nasıl işlediği hakkında mimari bilgi için bkz. SQL deyimi işleme. Ancak, varlığın denetlenilmesi gereken bazı durumlarda birleştirme daha iyi performans sağlar. Aksi takdirde, yinelenenlerin ortadan kaldırılmasını sağlamak için iç içe sorgunun dış sorgunun her sonucu için işlenmesi gerekir. Böyle durumlarda birleştirme yaklaşımı daha iyi sonuçlar verir.
Aşağıdaki örnekte hem bir alt sorgu SELECT hem de aynı sonuç kümesini ve yürütme planını döndüren bir birleşim SELECT gösterilmektedir:
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
Dış SELECT deyimde iç içe yerleştirilmiş bir alt sorgu aşağıdaki bileşenlere sahiptir:
- Normal
SELECTseçme listesi bileşenlerini içeren normal bir sorgu. - Bir veya daha fazla tablo veya görünüm adı içeren normal
FROMyan tümce. - İsteğe bağlı
WHEREbir yan tümce. - İsteğe bağlı
GROUP BYbir yan tümce. - İsteğe bağlı
HAVINGbir yan tümce.
Bir SELECT alt sorgunun sorgusu her zaman parantez içine alınır. Or COMPUTE yan tümcesi içeremez FOR BROWSE ve yalnızca bir ORDER BY yan tümce de belirtildiğinde bir TOP yan tümce içerebilir.
Bir alt sorgu dış , , WHEREHAVINGveya deyiminin SELECT veya INSERT yan tümcesinin içine ya da UPDATE başka bir DELETEalt sorgunun içine yerleştirilebilir. Sınır kullanılabilir belleğe ve sorgudaki diğer ifadelerin karmaşıklığına bağlı olarak değişse de en fazla 32 iç içe yerleştirme düzeyi mümkündür. Tek tek sorgular 32 düzeye kadar iç içe yerleştirmeyi desteklemez. Bir alt sorgu, tek bir değer döndürüyorsa bir ifadenin kullanabildiği her yerde görüntülenebilir.
Tablo dış sorguda değil de yalnızca alt sorguda görünüyorsa, bu tablodaki sütunlar çıkışa (dış sorgunun seçme listesi) eklenemez.
Alt sorgu içeren deyimler genellikle şu biçimlerden birini alır:
WHERE expression [NOT] IN (subquery)WHERE expression comparison_operator [ANY | ALL] (subquery)WHERE [NOT] EXISTS (subquery)
Bazı Transact-SQL deyimlerinde, alt sorgu bağımsız bir sorgu gibi değerlendirilebilir. Kavramsal olarak, alt sorgu sonuçları dış sorguyla değiştirilir (ancak SQL Server'ın Transact-SQL deyimlerini alt sorgularla nasıl işlediği zorunlu değildir).
Üç temel alt sorgu türü vardır. Şu şekilde olanlar:
- ile
INsunulan listelerde veya veya ileANYALLbir karşılaştırma işlecinin değiştirdiği listelerde çalışma. - Değiştirilmemiş bir karşılaştırma işleci ile tanıtılır ve tek bir değer döndürmesi gerekir.
- ile
EXISTSsunulan varlık testleri mi?
Alt sorgu kuralları
Alt sorgu aşağıdaki kısıtlamalara tabidir:
- Karşılaştırma işleciyle birlikte sunulan bir alt sorgunun seçme listesi yalnızca bir ifade veya sütun adı içerebilir (
EXISTSsırasıyla veINüzerinde veya liste üzerindeSELECT *çalışma dışında). - Dış sorgunun
WHEREyan tümcesi bir sütun adı içeriyorsa, alt sorgu seçme listesindeki sütunla birleştirme uyumlu olmalıdır. - Ntext, metin ve görüntü veri türleri, seçme alt sorgu listesinde kullanılamaz.
- Tek bir değer döndürmeleri gerektiğinden, değiştirilmemiş bir karşılaştırma işleci tarafından tanıtılan alt sorgular (anahtar sözcüğü
ANYveyaALLtarafından takip edilmeyen) veGROUP BYyan tümcelerini içeremezHAVING. - anahtar
DISTINCTsözcüğü, içerenGROUP BYalt sorgularla kullanılamaz. -
COMPUTEveINTOyan tümceleri belirtilemiyor. -
ORDER BYyalnızca aynı zamanda belirtildiğindeTOPbelirtilebilir. - Alt sorgu kullanılarak oluşturulan görünüm güncelleştirilemez.
- kurala göre ile
EXISTSsunulan bir alt sorgunun seçme listesinde tek sütun adı yerine yıldız işareti (*) bulunur. ileEXISTSsunulan bir alt sorgunun kuralları standart seçim listesiyle aynıdır çünkü ile sunulanEXISTSbir alt sorgu bir varlık testi oluşturur ve veriler yerine DOĞRU veya YANLIŞ döndürür.
Alt sorgulardaki sütun adlarını niteleme
Aşağıdaki örnekte, dış sorgunun yan tümcesindeki sütun, BusinessEntityID dış sorgu WHERE yan tümcesindeki (FROM) tablo adıyla örtük olarak nitelenmiş durumdadır.Sales.Store Alt sorgunun seçme listesindeki başvurusu CustomerID , alt sorgu FROM yan tümcesi tarafından, yani tablo tarafından nitelenmiştir Sales.Customer .
USE AdventureWorks2022;
GO
SELECT [Name]
FROM Sales.Store
WHERE BusinessEntityID NOT IN
(SELECT CustomerID
FROM Sales.Customer
WHERE TerritoryID = 5);
GO
Genel kural, bir deyimdeki sütun adlarının yan tümcesinde FROM başvurulan tablo tarafından aynı düzeyde örtük olarak nitelenmiş olmasıdır. Bir alt sorgunun yan tümcesinde FROM başvurulan tabloda bir sütun yoksa, dış sorgunun yan tümcesinde başvurulan tablo tarafından örtük olarak nitelenmiş FROM olur.
Bu örtük varsayımlar belirtildiğinde sorgu aşağıdaki gibi görünür:
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
Tablo adını açıkça belirtmek hiçbir zaman yanlış değildir ve açık niteliklere sahip tablo adları hakkındaki örtük varsayımları geçersiz kılmak her zaman mümkündür.
Önemli
Bir sütuna, alt sorgunun yan tümcesi tarafından başvuruda bulunulmayan bir alt sorguda FROM başvurulur, ancak dış sorgunun FROM yan tümcesi tarafından başvuruda bulunılan bir tabloda varsa, sorgu hatasız yürütülür. SQL Server, alt sorgudaki sütunu örtük olarak dış sorgudaki tablo adıyla niteler.
Birden çok iç içe yerleştirme düzeyi
Bir alt sorgu bir veya daha fazla alt sorgu içerebilir. Deyiminde herhangi bir sayıda alt sorgu iç içe yerleştirilebilir.
Aşağıdaki sorgu, aynı zamanda satış elemanı olan çalışanların adlarını bulur.
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
Sonuç kümesi aşağıdadır.
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)
En içteki sorgu, satış kişisi kimliklerini döndürür. Bir sonraki üst düzeydeki sorgu, bu satış elemanı kimlikleriyle değerlendirilir ve çalışanların kişi kimliği numaralarını döndürür. Son olarak, dış sorgu çalışanların adlarını bulmak için kişi kimliklerini kullanır.
Bu sorguyu birleştirme olarak da ifade edebilirsiniz:
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
Bağıntılı alt sorgular
Birçok sorgu, alt sorguyu bir kez yürütüp sonuçta elde edilen değeri veya değerleri WHERE dış sorgunun yan tümcesine değiştirerek değerlendirilebilir. Bağıntılı bir alt sorgu (yinelenen alt sorgu olarak da bilinir) içeren sorgularda, alt sorgu değerleri için dış sorguya bağlıdır. Bu, alt sorgunun, dış sorgu tarafından seçilebilen her satır için bir kez tekrar tekrar yürütüldüğünü gösterir.
Bu sorgu, her çalışanın adının ve soyadının bir örneğini alır ve tablodaki SalesPerson bonus 5000'dir ve ve tablolarında EmployeeSalesPerson çalışan kimlik numaraları eşleşmektedir.
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
Sonuç kümesi aşağıdadır.
LastName FirstName BusinessEntityID
-------------------------- ---------- ------------
Ansman-Wolfe Pamela 280
Saraiva José 282
(2 row(s) affected)
Bu deyimdeki önceki alt sorgu, dış sorgudan bağımsız olarak değerlendirilemez. için Employee.BusinessEntityIDbir değere ihtiyacı vardır, ancak SQL Server içindeki Employeefarklı satırları incelediğinden bu değer değişir.
Bu sorgu tam olarak bu şekilde değerlendirilir: SQL Server, her satırdaki değeri iç sorguya yazarak tablonun her satırını Employee sonuçlara eklemek üzere değerlendirir.
Örneğin, SQL Server ilk olarak için Syed Abbassatırını incelerse, değişkeni Employee.BusinessEntityID değerini 285alır ve SQL Server iç sorguyla değiştirilir. Bu iki sorgu örneği, bağıntılı alt sorgu ile önceki örneğin ayrıştırma işlemini temsil eden bir örnektir.
USE AdventureWorks2022;
GO
SELECT Bonus
FROM Sales.SalesPerson
WHERE BusinessEntityID = 285;
GO
Sonuç 0,00'dır (Syed Abbas satış temsilcisi olmadıkları için bonus almadım), bu nedenle dış sorgu şu şekilde değerlendirilir:
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
Bu false olduğundan, satırı Syed Abbas bağıntılı alt sorguyla önceki örnek sorgunun sonuçlarına dahil değildir. için satırıyla Pamela Ansman-Wolfeaynı yordamı uygulayın. Sonuçlar içerdiğinden, WHERE 5000 IN (5000) bu satırın sonuçlara dahil olduğunu görürsünüz.
Bağıntılı alt sorgular, dış sorgudaki FROM bir tablodaki sütunlara tablo değerli işlevin bağımsız değişkeni olarak başvurarak yan tümcesinde tablo değerli işlevler de içerebilir. Bu durumda, dış sorgunun her satırı için tablo değerli işlev alt sorguya göre değerlendirilir.
Alt sorgu türleri
Alt sorgular birçok yerde belirtilebilir:
- Diğer adlarla. Daha fazla bilgi için bkz. Tablo diğer adlarıyla alt sorgular.
- veya
INile.NOT INDaha fazla bilgi için bkz. IN içeren Alt Sorgular ve DEĞİl ALT Sorgular. - ,
UPDATEDELETEveINSERTdeyimlerinde. Daha fazla bilgi için bkz. UPDATE, DELETE ve INSERT Deyimlerindeki Alt Sorgular. - Karşılaştırma işleçleriyle. Daha fazla bilgi için bkz. Karşılaştırma işleçleriyle alt sorgular.
- ,
ANYveyaSOMEileALL. Daha fazla bilgi için bkz . ANY, SOME veya ALL tarafından değiştirilen karşılaştırma işleçleri. - ile.
IS [NOT] DISTINCT FROMDaha fazla bilgi için bkz . IS [NOT] DISTINCT FROM (Transact-SQL). - veya
EXISTSile.NOT EXISTSDaha fazla bilgi için bkz . EXISTS içeren Alt Sorgular ve VAR OLMAYAN Alt Sorgular. - İfade yerine. Daha fazla bilgi için bkz. İfade yerine kullanılan alt sorgular.
Tablo diğer adlarıyla alt sorgular
Alt sorgunun ve dış sorgunun aynı tabloya başvuracağı birçok deyim kendi kendine birleşimler (tabloyu kendisine birleştirme) olarak belirtilebilir. Örneğin, bir alt sorgu kullanarak belirli bir durumdaki çalışanların adreslerini bulabilirsiniz:
USE AdventureWorks2022;
GO
SELECT StateProvinceID, AddressID
FROM Person.Address
WHERE AddressID IN
(SELECT AddressID
FROM Person.Address
WHERE StateProvinceID = 39);
GO
Sonuç kümesi aşağıdadır.
StateProvinceID AddressID
----------- -----------
39 942
39 955
39 972
39 22660
(4 row(s) affected)
Ya da kendi kendine birleştirmeyi kullanabilirsiniz:
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
tablo diğer adları e1 ve e2 gereklidir çünkü kendisine katılmış olan tablo iki farklı rolde görünür. Diğer adlar, iç ve dış sorguda aynı tabloya başvuran iç içe sorgularda da kullanılabilir.
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
Açık tablo diğer adları, alt sorgudaki başvurunun Person.Address dış sorgudaki başvuruyla aynı anlama gelmez.
IN ile alt sorgular
(veya ) ile INNOT INsunulan bir alt sorgunun sonucu, sıfır veya daha fazla değerin listesidir. Alt sorgu sonuçları döndürdüğünde dış sorgu bunları kullanır.
Aşağıdaki sorgu, Adventure Works Cycles'ın yaptığı tüm tekerlek ürünlerinin adlarını bulur.
USE AdventureWorks2022;
GO
SELECT [Name]
FROM Production.Product
WHERE ProductSubcategoryID IN
(SELECT ProductSubcategoryID
FROM Production.ProductSubcategory
WHERE [Name] = 'Wheels');
GO
Sonuç kümesi aşağıdadır.
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)
Bu deyim iki adımda değerlendirilir. İlk olarak, iç sorgu adla Wheel (17) eşleşen alt kategori kimlik numarasını döndürür. İkinci olarak, bu değer dış sorguyla değiştirilir ve içindeki alt kategori kimlik numaralarıyla Production.Productbirlikte giden ürün adlarını bulur.
USE AdventureWorks2022;
GO
SELECT [Name]
FROM Production.Product
WHERE ProductSubcategoryID IN ('17');
GO
Bu ve benzer sorunlar için alt sorgu yerine birleştirme kullanmanın bir farkı, birleştirmenin sonuçta birden çok tablodan sütunları göstermenize olanak tanır. Örneğin, sonuçta ürün alt kategorisinin adını eklemek istiyorsanız birleştirme sürümü kullanmanız gerekir.
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
Sonuç kümesi aşağıdadır.
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)
Aşağıdaki sorgu, kredi derecelendirmesi iyi olan, Adventure Works Döngüleri'nin en az 20 ürün sipariş ettiği ve teslim etmek için ortalama sağlama süresi 16 günden az olan tüm satıcıların adını bulur.
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
Sonuç kümesi aşağıdadır.
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)
İç sorgu değerlendirilir ve alt sorgu niteliklerini karşılayan satıcıların kimlik numaraları oluşturulur. Dış sorgu daha sonra değerlendirilir. Hem iç hem de dış sorgunun yan tümcesine birden fazla koşul WHERE ekleyebilirsiniz.
Birleştirme kullanıldığında, aynı sorgu şu şekilde ifade edilir:
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
Birleştirme her zaman alt sorgu olarak ifade edilebilir. Bir alt sorgu genellikle birleşim olarak ifade edilebilir ancak her zaman ifade edilmeyebilir. Bunun nedeni birleşimlerin simetrik olmasıdır: tabloya AB her iki sırayla da katılabilir ve aynı yanıtı alabilirsiniz. Bir alt sorgu söz konusu olduğunda aynı durum geçerli değildir.
DEĞİl alt sorgular
anahtar sözcüğüyle NOT IN sunulan alt sorgular da sıfır veya daha fazla değerin listesini döndürür.
Aşağıdaki sorgu, tamamlanmamış bisikletlerin adlarını bulur.
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
Bu deyim birleştirmeye dönüştürülemez. Benzer olmayan birleştirmenin farklı bir anlamı vardır: Tamamlanmış bir bisiklet olmayan bazı alt kategorilerdeki ürünlerin adlarını bulur.
UPDATE, DELETE ve INSERT deyimlerindeki alt sorgular
Alt sorgular , , UPDATEDELETEve INSERT veri işleme (DML) deyimlerinde iç içe SELECTyerleştirilebilir.
Aşağıdaki örnek, tablodaki sütundaki ListPriceProduction.Product değeri ikiye katlar. Yan tümcesindeki WHERE alt sorgu, Purchasing.ProductVendor tablosunda güncelleştirilen satırları yalnızca tarafından BusinessEntitysağlanan satırlarla sınırlamak için tabloya başvurur1540.
USE AdventureWorks2022;
GO
UPDATE Production.Product
SET ListPrice = ListPrice * 2
WHERE ProductID IN
(SELECT ProductID
FROM Purchasing.ProductVendor
WHERE BusinessEntityID = 1540);
GO
Birleştirme kullanan eşdeğer UPDATE bir deyim aşağıdadır:
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
Diğer alt sorgularda aynı tablonun kendisine başvurulma ihtimaline karşı netlik sağlamak için hedef tablonun diğer adını kullanın:
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
Karşılaştırma işleçleri içeren alt sorgular
Alt sorgular karşılaştırma işleçlerinden biriyle (=, , < >>, , > =, <, ! >, ! <veya < =) tanıtılabilir.
Değiştirilmemiş bir karşılaştırma işleciyle (veya ANYtarafından takip ALL edilmeyen bir karşılaştırma işleci) tanıtılan bir alt sorgu, ile INsunulan alt sorgular gibi değerlerin listesi yerine tek bir değer döndürmelidir. Böyle bir alt sorgu birden fazla değer döndürürse, SQL Server bir hata iletisi görüntüler.
Değiştirilmemiş bir karşılaştırma işleciyle sunulan bir alt sorguyu kullanmak için, verilerinize ve sorunun doğasına göre alt sorgunun tam olarak bir değer döndüreceğini bilecek kadar bilgi sahibi olmanız gerekir.
Örneğin, her satış elemanının yalnızca bir satış bölgesini kapsadığını varsayarsanız ve kapsamındaki bölgede Linda Mitchellbulunan müşterileri bulmak istiyorsanız, basit = karşılaştırma işleciyle birlikte sunulan bir alt sorgu içeren bir deyim yazabilirsiniz.
USE AdventureWorks2022;
GO
SELECT CustomerID
FROM Sales.Customer
WHERE TerritoryID =
(SELECT TerritoryID
FROM Sales.SalesPerson
WHERE BusinessEntityID = 276);
GO
Ancak Linda Mitchell birden fazla satış bölgesini kapsadıysa bir hata iletisiyle sonuçlanır. Karşılaştırma işleci yerine = bir IN formülasyon kullanılabilir (=ANY aynı zamanda çalışır).
Değiştirilmemiş karşılaştırma işleçleriyle sunulan alt sorgular genellikle toplama işlevleri içerir çünkü bunlar tek bir değer döndürür. Örneğin, aşağıdaki deyim, liste fiyatı ortalama liste fiyatından büyük olan tüm ürünlerin adlarını bulur.
USE AdventureWorks2022;
GO
SELECT [Name]
FROM Production.Product
WHERE ListPrice >
(SELECT AVG (ListPrice)
FROM Production.Product);
GO
Değiştirilmemiş karşılaştırma işleçleriyle sunulan alt sorgular tek bir değer döndürmesi gerektiğinden, or yan tümcesinin GROUP BY tek bir değer döndürdüğünden emin olmadığınız sürece veya HAVING yan tümcelerini içeremezlerGROUP BY.HAVING Örneğin, aşağıdaki sorgu içindeki en düşük fiyatlı üründen daha yüksek fiyatlı ürünleri ProductSubcategoryID14bulur.
USE AdventureWorks2022;
GO
SELECT [Name]
FROM Production.Product
WHERE ListPrice >
(SELECT MIN (ListPrice)
FROM Production.Product
GROUP BY ProductSubcategoryID
HAVING ProductSubcategoryID = 14);
GO
, ANYveya tarafından SOMEdeğiştirilen karşılaştırma işleçleriALL
Alt sorguya neden olan karşılaştırma işleçleri ALL veya ANYanahtar sözcükleriyle değiştirilebilir.
SOME için ANYISO standart eşdeğeridir. Bu karşılaştırma işleçleri hakkında daha fazla bilgi için bkz . SOME | HERHANGI BIRI.
Değiştirilmiş karşılaştırma işleciyle sunulan alt sorgular sıfır veya daha fazla değerin listesini döndürür ve or GROUP BYHAVING yan tümcesi içerebilir. Bu alt sorgular ile EXISTSrestated olabilir.
Karşılaştırma işlecini > örnek olarak kullanmak, > ALL her değerden daha büyük anlamına gelir. Başka bir deyişle, en büyük değerden daha büyük anlamına gelir. Örneğin, > ALL (1, 2, 3) 3'ten büyük anlamına gelir.
> ANY en az bir değerden büyük, yani minimumdan büyük anlamına gelir. Yani > ANY (1, 2, 3) 1'den büyük demek.
ile alt sorgudaki > ALL bir satırın dış sorguda belirtilen koşulu karşılaması için, alt sorguyu tanıtan sütundaki değerin, alt sorgu tarafından döndürülen değerler listesindeki her değerden büyük olması gerekir.
Benzer şekilde, > ANY bir satırın dış sorguda belirtilen koşulu karşılaması için, alt sorguyu tanıtan sütundaki değerin, alt sorgu tarafından döndürülen değerler listesindeki değerlerden en az birinden büyük olması gerektiği anlamına gelir.
Aşağıdaki sorgu, tarafından ANYdeğiştirilen bir karşılaştırma işleciyle sunulan bir alt sorgu örneği sağlar. Liste fiyatları herhangi bir ürün alt kategorisinin en yüksek liste fiyatından büyük veya buna eşit olan ürünleri bulur.
USE AdventureWorks2022;
GO
SELECT [Name]
FROM Production.Product
WHERE ListPrice >= ANY
(SELECT MAX (ListPrice)
FROM Production.Product
GROUP BY ProductSubcategoryID);
GO
Her Product alt kategorisi için iç sorgu en yüksek liste fiyatını bulur. Dış sorgu bu değerlerin tümüne bakar ve hangi ürünün liste fiyatlarının herhangi bir ürün alt kategorisinin en yüksek liste fiyatından büyük veya buna eşit olduğunu belirler. olarak değiştirilirse ANYALL, sorgu yalnızca liste fiyatı iç sorguda döndürülen tüm liste fiyatlarından büyük veya buna eşit olan ürünleri döndürür.
Alt sorgu herhangi bir değer döndürmezse, sorgunun tamamı herhangi bir değer döndüremez.
= ANY işleci ile INeşdeğerdir. Örneğin, Adventure Works Cycles'ın yaptığı tüm tekerlek ürünlerinin adlarını bulmak için veya INkullanabilirsiniz= 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
her iki sorgu için de sonuç kümesi aşağıdadır:
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)
<> ANY Ancak işlecinden NOT INfarklıdır:
-
<> ANYnot = a veya değil = b veya not = c anlamına gelir -
NOT INnot = a, not = b ve not = c anlamına gelir -
<> ALLile aynı anlama gelirNOT IN
Örneğin, aşağıdaki sorgu herhangi bir satış elemanı tarafından kapsanmayan bir bölgede bulunan müşterileri bulur.
USE AdventureWorks2022;
GO
SELECT CustomerID
FROM Sales.Customer
WHERE TerritoryID <> ANY
(SELECT TerritoryID
FROM Sales.SalesPerson);
GO
Sonuçlar, satış bölgeleri NULLolan müşteriler dışında tüm müşterileri içerir çünkü müşteriye atanan her bölge bir satış sorumlusu tarafından kapsanmaktadır. İç sorgu, satış kişilerinin kapsadığı tüm satış bölgelerini bulur ve her bölge için dış sorgu, tek bir bölgede olmayan müşterileri bulur.
Aynı nedenle, bu sorguda kullandığınızda NOT IN sonuçlar müşterilerden hiçbirini içermez.
işleciyle <> ALL aynı sonuçları alabilirsiniz. Bu, ile NOT INeşdeğerdir.
Alt sorgular EXISTS
anahtar sözcüğüyle EXISTSbir alt sorgu sunulduğunda, alt sorgu bir varoluş testi olarak çalışır. Dış WHERE sorgunun yan tümcesi, alt sorgu tarafından döndürülen satırların mevcut olup olmadığını test eder. Alt sorgu aslında herhangi bir veri üretmez; veya TRUEdeğerini FALSE döndürür.
ile EXISTS sunulan bir alt sorgu aşağıdaki söz dizimine sahiptir: WHERE [NOT] EXISTS (subquery)
Aşağıdaki sorgu, Wheels alt kategorisindeki tüm ürünlerin adlarını bulur:
USE AdventureWorks2022;
GO
SELECT [Name]
FROM Production.Product
WHERE EXISTS
(SELECT *
FROM Production.ProductSubcategory
WHERE ProductSubcategoryID =
Production.Product.ProductSubcategoryID
AND [Name] = 'Wheels');
GO
Sonuç kümesi aşağıdadır.
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)
Bu sorgunun sonuçlarını anlamak için sırayla her ürünün adını göz önünde bulundurun. Bu değer alt sorgunun en az bir satır döndürmesine neden olur mu? Başka bir deyişle, sorgu varlık testinin değerlendirmesine TRUEneden olur mu?
ile EXISTS sunulan alt sorgular, aşağıdaki yollarla diğer alt sorgulardan biraz farklıdır:
- Anahtar sözcüğün
EXISTSönünde sütun adı, sabit veya başka bir ifade yoktur. - tarafından
EXISTStanıtılan bir alt sorgunun seçme listesi neredeyse her zaman yıldız işaretinden (*) oluşur. Yalnızca alt sorguda belirtilen koşullara uyan satırların mevcut olup olmadığını test ettiğiniz için sütun adlarını listelemek için bir neden yoktur.
EXISTS Anahtar sözcük önemlidir çünkü genellikle alt sorgular olmadan alternatif formülasyon yoktur. ile EXISTS oluşturulan bazı sorgular başka bir şekilde ifade edilemese de, birçok sorgu tarafından veya benzer INANY sonuçlar elde etmek için değiştirilen bir karşılaştırma işlecini kullanabilirALL.
Örneğin, yukarıdaki sorgu kullanılarak INifade edilebilir:
USE AdventureWorks2022;
GO
SELECT [Name]
FROM Production.Product
WHERE ProductSubcategoryID IN
(SELECT ProductSubcategoryID
FROM Production.ProductSubcategory
WHERE [Name] = 'Wheels');
GO
Alt sorgular NOT EXISTS
NOT EXISTS gibi EXISTSçalışır, ancak WHERE alt sorgu tarafından hiçbir satır döndürülmezse yan tümcesi karşılanır.
Örneğin, tekerlekler alt kategorisinde olmayan ürünlerin adlarını bulmak için:
USE AdventureWorks2022;
GO
SELECT [Name]
FROM Production.Product
WHERE NOT EXISTS
(SELECT *
FROM Production.ProductSubcategory
WHERE ProductSubcategoryID =
Production.Product.ProductSubcategoryID
AND [Name] = 'Wheels');
GO
İfade yerine kullanılan alt sorgular
Transact-SQL'de, bir alt sorgu, bir ifadenin liste dışında SELECT , UPDATE, INSERTve DELETE deyimlerinde kullanabildiği ORDER BYher yerde değiştirilebilir.
Aşağıdaki örnekte bu geliştirmeyi nasıl kullanabileceğiniz gösterilmektedir. Bu sorgu tüm dağ bisikleti ürünlerinin fiyatlarını, bunların ortalama fiyatını ve her dağ bisikletinin fiyatı ile ortalama fiyat arasındaki farkı bulur.
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
İlgili içerik
- IN (Transact-SQL)
- EXISTS (Transact-SQL)
- ALL (Transact-SQL)
- BAZI | ANY (Transact-SQL)
- Birleşimleri (SQL Server)
- Karşılaştırma İşleçleri (Transact-SQL)
- Sorgu işleme mimarisi kılavuzu
- Sorgu Deposu ile iş yüklerini izlemeye yönelik en iyi yöntemler
- SQL veritabanlarında akıllı sorgu işleme
- Kardinalite Tahmini (SQL Server)