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 Veritabanı
Azure SQL Yönetilen Örneği
Azure Synapse Analytics
Analitik Platform Sistemi (PDW)
Microsoft Fabric'te SQL veritabanı
Alt sorgu, bir SELECT, INSERT, UPDATE veya DELETE deyiminin ya da başka bir alt sorgunun içine iç içe yerleştirilmiş bir sorgudur.
Bu makaledeki kod örneklerinde AdventureWorks2025 veya AdventureWorksDW2025 örnek veritabanı kullanılır; bunları Microsoft SQL Server Samples and Community Projects ana sayfasından indirebilirsiniz.
Alt sorgu, bir ifadeye izin verilen her yerde kullanılabilir. Bu örnekte, bir alt sorgu, SELECT deyiminde MaxUnitPrice adlı bir 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 deyim ile alt sorgu içermeyen ancak anlamsal olarak eşdeğer bir sürüm arasında genellikle performans açısından 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
FROMtümce. - İsteğe bağlı bir
WHEREyan tümce. - İsteğe bağlı bir
GROUP BYyan tümce. - İsteğe bağlı
HAVINGyan tümcesi.
Bir SELECT alt sorgunun sorgusu her zaman parantez içine alınır. Bu, COMPUTE veya FOR BROWSE yan tümcesi içeremez ve yalnızca TOP yan tümcesi de belirtildiğinde ORDER BY yan tümcesini içerebilir.
Bir alt sorgu, dış SELECT, INSERT, UPDATE veya DELETE deyiminin WHERE ya da HAVING yan tümcesi içinde ya da başka bir alt sorgunun içinde iç içe yer alabilir. 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. Tekil sorgular, 32 düzeye kadar iç içe geçmeyi 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ış sorgunun içine yerleştirilir (ancak bu, SQL Server'ın alt sorgu içeren Transact-SQL deyimlerini gerçekte bu şekilde işlediği anlamına gelmez).
Üç temel alt sorgu türü vardır. Şunlar:
-
INile sunulan veyaANYya daALLile değiştirilen bir karşılaştırma işleci tarafından değiştirilen listeler üzerinde işlem yapın. - Değiştirilmemiş bir karşılaştırma işleci ile tanıtılır ve tek bir değer döndürmesi gerekir.
-
EXISTSile sunulan varlık testleri mi?
Alt sorgu kuralları
Alt sorgu aşağıdaki kısıtlamalara tabidir:
- Bir karşılaştırma işleciyle kullanılan bir alt sorgunun SELECT listesi yalnızca bir ifade veya sütun adı içerebilir (
EXISTSveINöğelerinin sırasıylaSELECT *ya da bir liste üzerinde işlem yapması durumu 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şleciyle kullanılan alt sorgular (yani ardından
ANYveyaALLanahtar sözcüğü gelmeyen bir işleçle)GROUP BYveHAVINGtümcelerini içeremez. - anahtar
DISTINCTsözcüğü, içerenGROUP BYalt sorgularla kullanılamaz. -
COMPUTEveINTOtümceleri belirtilemez. -
ORDER BY, yalnızcaTOPde belirtildiğinde 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. 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çim listesindeki CustomerID başvurusu, alt sorgunun FROM tümcesi, yani Sales.Customer tablosu tarafından nitelenir.
USE AdventureWorks2022;
GO
SELECT [Name]
FROM Sales.Store
WHERE BusinessEntityID NOT IN
(SELECT CustomerID
FROM Sales.Customer
WHERE TerritoryID = 5);
GO
Genel kural, bir ifadedeki sütun adlarının aynı düzeydeki FROM yan tümcesinde başvurulan tablo ile örtük olarak nitelendirilmesidir. Bir alt sorgunun FROM yan tümcesinde başvurulan tabloda bir sütun yoksa, bu sütun dış sorgunun FROM yan tümcesinde başvurulan tablo tarafından örtük olarak nitelenir.
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 alt sorguda bir sütuna başvuruluyorsa, bu sütun alt sorgunun FROM yan tümcesinde başvurulan tabloda bulunmuyor, ancak dış sorgunun FROM yan tümcesinde başvurulan bir tabloda bulunuyorsa, sorgu hata vermeden 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 geçme düzeyi
Bir alt sorgu bir veya daha fazla alt sorgu içerebilir. Bir ifadede istediğiniz 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ış temsilcisi 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 kimlik numaralarını 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, SalesPerson tablosundaki bonusu 5000 olan ve çalışan kimlik numaraları Employee ile SalesPerson tablolarında eşleşen her çalışanın adını ve soyadını tek bir kez getirir.
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 şu şekilde değerlendirilir: SQL Server, Employee tablosunun her satırındaki değeri iç sorguda yerine koyarak, her satırın sonuçlara dahil edilip edilmeyeceğini belirler.
Örneğin, SQL Server önce Syed Abbas satırını incelerse, Employee.BusinessEntityID değişkeni 285 değerini alır; SQL Server da bu değeri iç sorguda yerine koyar. 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 yanlış olduğundan, Syed Abbas için olan satır bağıntılı alt sorgu içeren önceki örnek sorgunun sonuçlarında yer almaz.
Pamela Ansman-Wolfe satırı için aynı işlemi 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, tablo değerli işlevin bağımsız değişkeni olarak dış sorgudaki bir tablonun sütunlarına başvurarak, FROM yan tümcesinde tablo değerli işlevler de içerebilir. Bu durumda, dış sorgudaki 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.
-
INveyaNOT INile. Daha fazla bilgi için bkz. IN içeren alt sorgular ve NOT IN içeren alt sorgular. -
UPDATE,DELETEveINSERTifadelerinde. Daha fazla bilgi için bkz. , UPDATEve DELETE Deyimlerindeki INSERTAlt Sorgular. - Karşılaştırma işleçleri ile. Daha fazla bilgi için bkz. Karşılaştırma işleçleriyle alt sorgular.
-
ANY,SOMEveyaALLile. Daha fazla bilgi için bkz . ANY, SOME veya ALL tarafından değiştirilen karşılaştırma işleçleri. -
IS [NOT] DISTINCT FROMile. Daha fazla bilgi için bkz. IS [NOT] DISTINCT FROM (Transact-SQL). -
EXISTSveyaNOT EXISTSile. Daha fazla bilgi için bkz. EXISTS ile alt sorgular ve NOT EXISTS ile alt sorgular. - Bir ifadenin yerine. Daha fazla bilgi için bkz. İfade yerine kullanılan alt sorgular.
Tablo takma 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 takma adları e1 ve e2 gereklidir çünkü kendisiyle birleştirilen tablo iki farklı rolde yer alır. Takma adlar, hem iç hem de 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
Tablo takma adlarının açıkça belirtilmesi, alt sorgudaki Person.Address başvurusunun dış sorgudaki başvuruyla aynı şeyi ifade etmediğini netleştirir.
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ış sorguda yerine konur; ardından dış sorgu, Production.Product içindeki alt kategori kimlik numaralarına karşılık gelen ü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 işlemi her zaman bir 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.
NOT IN içeren 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 ifade join işlemine dönüştürülemez. Buna karşılık gelen eşit olmayan birleştirmenin farklı bir anlamı vardır: Bitmiş bisiklet olmayan bir alt kategoride bulunan ürünlerin adlarını bulur.
UPDATE, DELETE ve INSERT ifadelerinde alt sorgular
Alt sorgular, UPDATE, DELETE, INSERT ve SELECT veri işleme (DML) deyimlerinde iç içe kullanılabilir.
Aşağıdaki örnek, tablodaki sütundaki ListPriceProduction.Product değeri ikiye katlar.
WHERE yan tümcesindeki alt sorgu, Product tablosunda güncelleştirilen satırları yalnızca BusinessEntity1540 tarafından sağlananlarla sınırlamak için Purchasing.ProductVendor tablosuna başvurur.
USE AdventureWorks2022;
GO
UPDATE Production.Product
SET ListPrice = ListPrice * 2
WHERE ProductID IN
(SELECT ProductID
FROM Purchasing.ProductVendor
WHERE BusinessEntityID = 1540);
GO
İşte join kullanarak yazılmış eşdeğer bir UPDATE ifade:
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 (yani ardından ANY veya ALL gelmeyen bir karşılaştırma işleciyle) başlatılan bir alt sorgu, IN ile başlatılan alt sorgularda olduğu gibi bir değerler 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 kullanılan alt sorguların tek bir değer döndürmesi gerektiğinden, GROUP BY veya HAVING yan tümcelerini, ancak GROUP BY ya da HAVING yan tümcesinin kendisinin tek bir değer döndürdüğünü biliyorsanız içerebilirler. Ö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
ANY, SOME veya ALL ile değiştirilen karşılaştırma işleçleri
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 | ANY.
Değiştirilmiş bir karşılaştırma işleci kullanılan alt sorgular, sıfır veya daha fazla değer içeren bir liste döndürür ve GROUP BY veya HAVING yan tümcesi içerebilir. Bu alt sorgular EXISTS kullanılarak yeniden ifade edilebilir.
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, ANY ile değiştirilmiş bir karşılaştırma işleciyle tanıtılan bir alt sorgunun örneğini verir. 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 ürettiği tüm tekerlek ürünlerinin adlarını bulmak için IN veya = ANY kullanabilirsiniz.
--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)
Ancak, <> ANY işleci NOT IN öğesinden farklıdır:
-
<> ANY, a'ya eşit değil veya b'ye eşit değil veya c'ye eşit değil 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.
<> ALL işleciyle aynı sonuçları elde edebilirsiniz; bu da NOT IN ile eş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 gerçekte hiçbir veri üretmez; TRUE veya FALSE değerini 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 sonucunun TRUE olmasına neden 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.
EXISTS ile oluşturulan bazı sorgular başka hiçbir şekilde ifade edilemese de, birçok sorgu benzer sonuçlar elde etmek için IN ya da ANY veya ALL ile değiştirilmiş bir karşılaştırma işleci kullanabilir.
Ö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
NOT EXISTS ile alt sorgular
NOT EXISTS, EXISTS gibi çalışır, ancak alt sorgu hiçbir satır döndürmezse WHERE ifadesi 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, ORDER BY listesi dışında, bir ifadenin kullanılabildiği her yerde SELECT, UPDATE, INSERT ve DELETE deyimlerinde kullanılabilir.
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)
- SOME | 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)