国产成人精品亚洲777人妖,欧美日韩精品一区视频,最新亚洲国产,国产乱码精品一区二区亚洲

您的位置:首頁技術(shù)文章
文章詳情頁

SQL Server的子查詢詳解

瀏覽:2日期:2023-05-02 10:03:27
目錄
  • 一、子查詢基礎(chǔ)知識
  • 二、子查詢規(guī)則
  • 三、限定子查詢中的列名
  • 四、子查詢的多層嵌套
  • 五、相關(guān)子查詢
  • 六、子查詢類型
  • 總結(jié)

一、子查詢基礎(chǔ)知識

子查詢是嵌套在SELECT、INSERT、UPDATE、DELETE語句中或另一個子查詢中的查詢。
可以在允許表達(dá)式的任何位置使用子查詢。

示例:

USE AdventureWorks2016;GOSELECT Ord.SalesOrderID, Ord.OrderDate,    (SELECT MAX(OrdDet.UnitPrice)     FROM Sales.SalesOrderDetail AS OrdDet     WHERE Ord.SalesOrderID = OrdDet.SalesOrderID) AS MaxUnitPriceFROM Sales.SalesOrderHeader AS Ord;GO

子查詢也稱為內(nèi)部查詢或內(nèi)部選擇,而包含子查詢的語句也稱為外部查詢或外部選擇。

許多包含子查詢的 Transact-SQL 語句也可以表述為聯(lián)接。其他問題只能用子查詢提出。在 Transact-SQL 中,包含子查詢的語句與不包含子查詢的語義等效版本之間通常沒有性能差異。但是,在某些必須檢查是否存在的情況下,聯(lián)接會產(chǎn)生更好的性能。否則,必須為外部查詢的每個結(jié)果處理嵌套查詢,以確保消除重復(fù)項。在這種情況下,聯(lián)接方法將產(chǎn)生更好的結(jié)果。

以下示例顯示了返回相同結(jié)果集和執(zhí)行計劃的子查詢和聯(lián)接:

USE AdventureWorks2016;GO/* SELECT statement built using a subquery. */SELECT [Name]FROM Production.ProductWHERE 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ī)查詢。
  • 包含一個或多個表或視圖名稱的常規(guī)子句。
  • 可選:WHERE、GROUP BY、HAVING。

子查詢的 SELECT 查詢始終括在括號中。它不能包含 or 子句,并且只能在還指定 TOP 子句時才包含子句。

子查詢可以嵌套在外部 WHERE、HAVING、SELECT、INSERT、UPDATE、DELETE或語句的 or 子句中,也可以嵌套在另一個子查詢中。最多可以嵌套 32 個級別,但限制因可用內(nèi)存和查詢中其他表達(dá)式的復(fù)雜性而異。單個查詢可能不支持嵌套多達(dá) 32 個級別。如果子查詢返回單個值,則子查詢可以出現(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 語句中,可以像計算獨(dú)立查詢一樣計算子查詢。從概念上講,子查詢結(jié)果被替換到外部查詢中(盡管這不一定是 SQL Server 實際處理帶有子查詢的 Transact-SQL 語句的方式)。

有三種基本類型的子查詢:

對引入的列表進(jìn)行操作,或者比較運(yùn)算符由 INANY或ALL 修改的列表。
使用未修改的比較運(yùn)算符引入,并且必須返回單個值。
是否使用EXISTS引入存在性測試。

二、子查詢規(guī)則

  • 使用比較運(yùn)算符引入的子查詢的選擇列表只能包含一個表達(dá)式或列名。
  • 如果外部查詢的子句包含列名,則該子句必須與子查詢選擇列表中的列連接兼容。
  • ntext、text 和 image 數(shù)據(jù)類型不能在子查詢的選擇列表中使用。
  • 由于它們必須返回單個值,因此由未修改的比較運(yùn)算符(不后跟關(guān)鍵字或)引入的子查詢不能包含 and 子句。
  • 關(guān)鍵字不能與包含 的子查詢一起使用。
  • 不能指定 and 子句。
  • ORDER BY只有在也指定TOP時才能指定。
  • 無法使用子查詢創(chuàng)建的視圖進(jìn)行更新。

三、限定子查詢中的列名

示例:外部查詢子句中的 BusinessEntityID 列由外部查詢子句 (Sales.Store) 中的表名隱式限定。子查詢的選擇列表中對 CustomerID 的引用由子查詢子句(即 Sales.Customer 表)限定。

USE AdventureWorks2016;GOSELECT [Name]FROM Sales.StoreWHERE BusinessEntityID NOT IN    (SELECT CustomerID     FROM Sales.Customer     WHERE TerritoryID = 5);GO

一般,語句中的列名由同一級別的子句中引用的表隱式限定。如果子查詢子句中引用的表中不存在列,則外部查詢子句中引用的表將隱式限定該列。

下面是指定這些隱式假設(shè)的查詢的外觀:

USE AdventureWorks2016;GOSELECT [Name]FROM Sales.StoreWHERE Sales.Store.BusinessEntityID NOT IN    (SELECT Sales.Customer.CustomerID     FROM Sales.Customer     WHERE TerritoryID = 5);GO

顯式聲明表名永遠(yuǎn)不會錯,并且始終可以使用顯式限定覆蓋有關(guān)表名的隱式假設(shè)。

四、子查詢的多層嵌套

子查詢本身可以包含一個或多個子查詢。任意數(shù)量的子查詢可以嵌套在一個語句中。

示例:查詢查找同時也是銷售人員的員工的姓名。

USE AdventureWorks2016;GOSELECT LastName, FirstNameFROM Person.PersonWHERE BusinessEntityID IN    (SELECT BusinessEntityID     FROM HumanResources.Employee     WHERE BusinessEntityID IN(SELECT BusinessEntityID FROM Sales.SalesPerson)    );GO

輸出:

最里面的查詢返回銷售人員 ID。下一個更高級別查詢使用這些銷售人員 ID 進(jìn)行評估,并返回員工的聯(lián)系人 ID 號。最后,外部查詢使用聯(lián)系人 ID 查找員工的姓名。

還可以將此查詢表示為聯(lián)接:

USE AdventureWorks2016;GOSELECT LastName, FirstNameFROM Person.Person cINNER JOIN HumanResources.Employee eON c.BusinessEntityID = e.BusinessEntityIDJOIN Sales.SalesPerson sON e.BusinessEntityID = s.BusinessEntityID;GO

五、相關(guān)子查詢

可以通過執(zhí)行一次子查詢并將結(jié)果值替換到外部查詢的子句中來計算許多查詢。在包含相關(guān)子查詢(也稱為重復(fù)子查詢)的查詢中,子查詢依賴于其值的外部查詢。這意味著子查詢將重復(fù)執(zhí)行,外部查詢可能選擇的每一行執(zhí)行一次。

示例:

USE AdventureWorks2016;GOSELECT DISTINCT c.LastName, c.FirstName, e.BusinessEntityIDFROM Person.Person AS c JOIN HumanResources.Employee AS eON e.BusinessEntityID = c.BusinessEntityIDWHERE 5000.00 IN    (SELECT Bonus    FROM Sales.SalesPerson sp    WHERE e.BusinessEntityID = sp.BusinessEntityID) ;GO

輸出結(jié)果:

此語句中的上一個子查詢不能獨(dú)立于外部查詢進(jìn)行計算。它需要 Employee.BusinessEntityID 的值,但此值會隨著 SQL Server 檢查 Employee 中的不同行而更改。 這正是計算此查詢的方式:SQL Server 通過將每行中的值替換為內(nèi)部查詢來考慮將 Employee 表的每一行包含在結(jié)果中。 例如,如果 SQL Server 首先檢查 的行,則變量 Employee.BusinessEntityID 采用值 285,SQL Server 將其替換到內(nèi)部查詢中。這兩個查詢示例表示具有相關(guān)子查詢的前一個示例的分解。

USE AdventureWorks2016;GOSELECT BonusFROM Sales.SalesPersonWHERE BusinessEntityID = 285;GO

結(jié)果為 0.00(沒有收到獎金,因為他們不是銷售人員),因此外部查詢的計算結(jié)果為:

USE AdventureWorks2016;GOSELECT LastName, FirstNameFROM Person.Person AS c JOIN HumanResources.Employee AS eON e.BusinessEntityID = c.BusinessEntityIDWHERE 5000 IN (0.00);GO

由于這是 false,因此 的行不包含在具有相關(guān)子查詢的上一個示例查詢的結(jié)果中。對 的行執(zhí)行相同的過程。您將看到此行包含在結(jié)果中,因為包含結(jié)果。

小結(jié):相關(guān)子查詢還可以通過在外部查詢中引用表中的列作為表值函數(shù)的參數(shù),在子句中包含表值函數(shù)。在這種情況下,對于外部查詢的每一行,將根據(jù)子查詢計算表值函數(shù)。

六、子查詢類型

  • 帶別名。
  • 帶IN或NOT IN。
  • 在UPDATE、DELETE 和 INSERT 語句中。
  • 使用比較運(yùn)算符。
  • 使用 ANY、SOME 或 ALL。
  • 跟 IS [NOT] DISTINCT FROM。
  • 帶 EXISTS或 NOT EXISTS。
  • 代替表達(dá)式。

總結(jié)

如果在子查詢中引用的列在子查詢中不存在,但存在于外部查詢的子句引用的表中,則查詢將執(zhí)行而不會出錯。SQL Server 使用外部查詢中的表名隱式限定子查詢中的列。

到此這篇關(guān)于SQL Server的子查詢詳解的文章就介紹到這了,更多相關(guān)SQL Server子查詢內(nèi)容請搜索以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持!

標(biāo)簽: MsSQL
主站蜘蛛池模板: 唐海县| 长顺县| 永泰县| 施秉县| 卫辉市| 奉化市| 库尔勒市| 溆浦县| 山阳县| 鸡东县| 桑日县| 诏安县| 泰安市| 新营市| 衢州市| 来宾市| 扎赉特旗| 吴忠市| 吉木乃县| 文化| 屯昌县| 六盘水市| 明光市| 涞源县| 弋阳县| 建德市| 汉源县| 德阳市| 洛南县| 广河县| 韩城市| 邵东县| 五原县| 金平| 容城县| 封开县| 荥经县| 阜阳市| 台中县| 广汉市| 修水县|