Aracılığıyla paylaş


Alt Sorgular (SQL Server)

Şunlar için geçerlidir:SQL ServerAzure SQL DatabaseAzure SQL Managed InstanceAzure Synapse AnalyticsAnalitik 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 SELECT seçme listesi bileşenlerini içeren normal bir sorgu.
  • Bir veya daha fazla tablo veya görünüm adı içeren normal FROM yan tümce.
  • İsteğe bağlı WHERE bir yan tümce.
  • İsteğe bağlı GROUP BY bir yan tümce.
  • İsteğe bağlı HAVING bir 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 ile ANYALLbir 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 ( EXISTS sırasıyla ve IN üzerinde veya liste üzerinde SELECT * çalışma dışında).
  • Dış sorgunun WHERE yan 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üğü ANY veya ALLtarafından takip edilmeyen) ve GROUP BY yan tümcelerini içeremezHAVING.
  • anahtar DISTINCT sözcüğü, içeren GROUP BYalt sorgularla kullanılamaz.
  • COMPUTE ve INTO yan tümceleri belirtilemiyor.
  • ORDER BY yalnızca aynı zamanda belirtildiğinde TOP belirtilebilir.
  • 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. ile EXISTS sunulan bir alt sorgunun kuralları standart seçim listesiyle aynıdır çünkü ile sunulan EXISTS bir 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:

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:

  • <> ANY not = a veya değil = b veya not = c anlamına gelir
  • NOT IN not = a, not = b ve not = c anlamına gelir
  • <> ALL ile aynı anlama gelir NOT 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 EXISTS tanı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