這篇文章主要介紹“SQL Server子查詢的規(guī)則是什么”的相關(guān)知識(shí),小編通過實(shí)際案例向大家展示操作過程,操作方法簡單快捷,實(shí)用性強(qiáng),希望這篇“SQL Server子查詢的規(guī)則是什么”文章能幫助大家解決問題。
成都創(chuàng)新互聯(lián)公司專注于朔州網(wǎng)站建設(shè)服務(wù)及定制,我們擁有豐富的企業(yè)做網(wǎng)站經(jīng)驗(yàn)。 熱誠為您提供朔州營銷型網(wǎng)站建設(shè),朔州網(wǎng)站制作、朔州網(wǎng)頁設(shè)計(jì)、朔州網(wǎng)站官網(wǎng)定制、小程序設(shè)計(jì)服務(wù),打造朔州網(wǎng)絡(luò)公司原創(chuàng)品牌,更為您提供朔州網(wǎng)站排名全網(wǎng)營銷落地服務(wù)。
子查詢是嵌套在SELECT、INSERT、UPDATE、DELETE語句中或另一個(gè)子查詢中的查詢。
可以在允許表達(dá)式的任何位置使用子查詢。
示例:
USE AdventureWorks2016; 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
子查詢也稱為內(nèi)部查詢或內(nèi)部選擇,而包含子查詢的語句也稱為外部查詢或外部選擇。
許多包含子查詢的 Transact-SQL 語句也可以表述為聯(lián)接。其他問題只能用子查詢提出。在 Transact-SQL 中,包含子查詢的語句與不包含子查詢的語義等效版本之間通常沒有性能差異。但是,在某些必須檢查是否存在的情況下,聯(lián)接會(huì)產(chǎn)生更好的性能。否則,必須為外部查詢的每個(gè)結(jié)果處理嵌套查詢,以確保消除重復(fù)項(xiàng)。在這種情況下,聯(lián)接方法將產(chǎn)生更好的結(jié)果。
以下示例顯示了返回相同結(jié)果集和執(zhí)行計(jì)劃的子查詢和聯(lián)接:
USE AdventureWorks2016; 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
嵌套在外部 SELECT 語句中的子查詢具有以下組件:
包含常規(guī)選擇列表組件的常規(guī)查詢。
包含一個(gè)或多個(gè)表或視圖名稱的常規(guī)子句。
可選:WHERE、GROUP BY、HAVING。
子查詢的 SELECT 查詢始終括在括號(hào)中。它不能包含 or 子句,并且只能在還指定 TOP 子句時(shí)才包含子句。
子查詢可以嵌套在外部 WHERE、HAVING、SELECT、INSERT、UPDATE、DELETE或語句的 or 子句中,也可以嵌套在另一個(gè)子查詢中。最多可以嵌套 32 個(gè)級(jí)別,但限制因可用內(nèi)存和查詢中其他表達(dá)式的復(fù)雜性而異。單個(gè)查詢可能不支持嵌套多達(dá) 32 個(gè)級(jí)別。如果子查詢返回單個(gè)值,則子查詢可以出現(xiàn)在可以使用表達(dá)式的任何位置。
如果表僅出現(xiàn)在子查詢中而不出現(xiàn)在外部查詢中,則該表中的列不能包含在輸出(外部查詢的選擇列表)中。
包含子查詢的語句通常采用以下格式之一:
WHERE expression [NOT] IN (subquery)
WHERE expression comparison_operator [ANY | ALL] (subquery)
WHERE [NOT] EXISTS (subquery)
在某些 Transact-SQL 語句中,可以像計(jì)算獨(dú)立查詢一樣計(jì)算子查詢。從概念上講,子查詢結(jié)果被替換到外部查詢中(盡管這不一定是 SQL Server 實(shí)際處理帶有子查詢的 Transact-SQL 語句的方式)。
有三種基本類型的子查詢:
對(duì)引入的列表進(jìn)行操作,或者比較運(yùn)算符由 INANY或ALL 修改的列表。
使用未修改的比較運(yùn)算符引入,并且必須返回單個(gè)值。
是否使用EXISTS引入存在性測試。
使用比較運(yùn)算符引入的子查詢的選擇列表只能包含一個(gè)表達(dá)式或列名。
如果外部查詢的子句包含列名,則該子句必須與子查詢選擇列表中的列連接兼容。
ntext、text 和 image 數(shù)據(jù)類型不能在子查詢的選擇列表中使用。
由于它們必須返回單個(gè)值,因此由未修改的比較運(yùn)算符(不后跟關(guān)鍵字或)引入的子查詢不能包含 and 子句。
關(guān)鍵字不能與包含 的子查詢一起使用。
不能指定 and 子句。
ORDER BY只有在也指定TOP時(shí)才能指定。
無法使用子查詢創(chuàng)建的視圖進(jìn)行更新。
示例:外部查詢子句中的 BusinessEntityID 列由外部查詢子句 (Sales.Store) 中的表名隱式限定。子查詢的選擇列表中對(duì) CustomerID 的引用由子查詢子句(即 Sales.Customer 表)限定。
USE AdventureWorks2016; GO SELECT [Name] FROM Sales.Store WHERE BusinessEntityID NOT IN (SELECT CustomerID FROM Sales.Customer WHERE TerritoryID = 5); GO
一般,語句中的列名由同一級(jí)別的子句中引用的表隱式限定。如果子查詢子句中引用的表中不存在列,則外部查詢子句中引用的表將隱式限定該列。
下面是指定這些隱式假設(shè)的查詢的外觀:
USE AdventureWorks2016; GO SELECT [Name] FROM Sales.Store WHERE Sales.Store.BusinessEntityID NOT IN (SELECT Sales.Customer.CustomerID FROM Sales.Customer WHERE TerritoryID = 5); GO
顯式聲明表名永遠(yuǎn)不會(huì)錯(cuò),并且始終可以使用顯式限定覆蓋有關(guān)表名的隱式假設(shè)。
子查詢本身可以包含一個(gè)或多個(gè)子查詢。任意數(shù)量的子查詢可以嵌套在一個(gè)語句中。
示例:查詢查找同時(shí)也是銷售人員的員工的姓名。
USE AdventureWorks2016; GO SELECT LastName, FirstName FROM Person.Person WHERE BusinessEntityID IN (SELECT BusinessEntityID FROM HumanResources.Employee WHERE BusinessEntityID IN (SELECT BusinessEntityID FROM Sales.SalesPerson) ); GO
輸出:
最里面的查詢返回銷售人員 ID。下一個(gè)更高級(jí)別查詢使用這些銷售人員 ID 進(jìn)行評(píng)估,并返回員工的聯(lián)系人 ID 號(hào)。最后,外部查詢使用聯(lián)系人 ID 查找員工的姓名。
還可以將此查詢表示為聯(lián)接:
USE AdventureWorks2016; 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
可以通過執(zhí)行一次子查詢并將結(jié)果值替換到外部查詢的子句中來計(jì)算許多查詢。在包含相關(guān)子查詢(也稱為重復(fù)子查詢)的查詢中,子查詢依賴于其值的外部查詢。這意味著子查詢將重復(fù)執(zhí)行,外部查詢可能選擇的每一行執(zhí)行一次。
示例:
USE AdventureWorks2016; 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
輸出結(jié)果:
此語句中的上一個(gè)子查詢不能獨(dú)立于外部查詢進(jìn)行計(jì)算。它需要 Employee.BusinessEntityID 的值,但此值會(huì)隨著 SQL Server 檢查 Employee 中的不同行而更改。 這正是計(jì)算此查詢的方式:SQL Server 通過將每行中的值替換為內(nèi)部查詢來考慮將 Employee 表的每一行包含在結(jié)果中。 例如,如果 SQL Server 首先檢查 的行,則變量 Employee.BusinessEntityID 采用值 285,SQL Server 將其替換到內(nèi)部查詢中。這兩個(gè)查詢示例表示具有相關(guān)子查詢的前一個(gè)示例的分解。
USE AdventureWorks2016; GO SELECT Bonus FROM Sales.SalesPerson WHERE BusinessEntityID = 285; GO
結(jié)果為 0.00(沒有收到獎(jiǎng)金,因?yàn)樗麄儾皇卿N售人員),因此外部查詢的計(jì)算結(jié)果為:
USE AdventureWorks2016; 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
由于這是 false,因此 的行不包含在具有相關(guān)子查詢的上一個(gè)示例查詢的結(jié)果中。對(duì) 的行執(zhí)行相同的過程。您將看到此行包含在結(jié)果中,因?yàn)榘Y(jié)果。
小結(jié):相關(guān)子查詢還可以通過在外部查詢中引用表中的列作為表值函數(shù)的參數(shù),在子句中包含表值函數(shù)。在這種情況下,對(duì)于外部查詢的每一行,將根據(jù)子查詢計(jì)算表值函數(shù)。
帶別名。
帶IN或NOT IN。
在UPDATE、DELETE 和 INSERT 語句中。
使用比較運(yùn)算符。
使用 ANY、SOME 或 ALL。
跟 IS [NOT] DISTINCT FROM。
帶 EXISTS或 NOT EXISTS。
代替表達(dá)式。
關(guān)于“SQL Server子查詢的規(guī)則是什么”的內(nèi)容就介紹到這里了,感謝大家的閱讀。如果想了解更多行業(yè)相關(guān)的知識(shí),可以關(guān)注創(chuàng)新互聯(lián)行業(yè)資訊頻道,小編每天都會(huì)為大家更新不同的知識(shí)點(diǎn)。