日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當前位置: 首頁 > 编程资源 > 综合教程 >内容正文

综合教程

Sql 子查询

發(fā)布時間:2024/1/3 综合教程 22 生活家
生活随笔 收集整理的這篇文章主要介紹了 Sql 子查询 小編覺得挺不錯的,現(xiàn)在分享給大家,幫大家做個參考.

子查詢本質(zhì)上是嵌套進其他SELECT,UPDATE,INSERT,DELETE語句的一個被限制的SELECT語句,在子查詢中,只有下面幾個子句可以使用

SELECT子句(必須)
FROM子句(必選)
WHERE子句(可選)
GROUP BY(可選)
HAVING(可選)
ORDER BY(只有在TOP關(guān)鍵字被使用時才可用)

子查詢也可以嵌套在其他子查詢中,這個嵌套最多可達32層。子查詢也叫內(nèi)部查詢(Inner query)或者內(nèi)部選擇(Inner Select),而包含子查詢的查詢語句也叫做外部查詢(Outter)或者外部選擇(Outer Select)。

通常來講,子查詢按照子查詢所返回數(shù)據(jù)的類型,可以分為三種,分別為:

返回一張數(shù)據(jù)表(Table)
返回一列值(Column)
返回單個值(Scalar)

子查詢作為數(shù)據(jù)源使用

當子查詢在外部查詢的FROM子句之后使用時,子查詢被當作一個數(shù)據(jù)源使用,即使這時子查詢只返回一個單一值(Scalar)或是一列值(Column),在這里依然可以看作一個特殊的數(shù)據(jù)源,即一個二維數(shù)據(jù)表(Table).作為數(shù)據(jù)源使用的子查詢很像一個View(視圖),只是這個子查詢只是臨時存在,并不包含在數(shù)據(jù)庫中。

比如這個語句:

SELECT     P.ProductID, P.Name, P.ProductNumber, M.Name AS ProductModelName
FROM         Production.Product AS P INNER JOIN
(SELECT     Name, ProductModelID
 FROM          Production.ProductModel) AS M 
ON P.ProductModelID = M.ProductModelID

上述子查詢語句將ProductModel表中的子集M,作為數(shù)據(jù)源(表)和Product表進行內(nèi)連接

作為數(shù)據(jù)源使用也是子查詢最簡單的應用。

子查詢作為選擇條件使用

作為選擇條件的子查詢也是子查詢相對最復雜的應用.

作為選擇條件的子查詢是那些只返回一列(Column)的子查詢,如果作為選擇條件使用,即使只返回單個值,也可以看作是只有一行一列.比如:

在AdventureWorks中:

我想取得總共請病假天數(shù)大于68小時的員工:

SELECT [FirstName]
      ,[MiddleName]
      ,[LastName]
  FROM [AdventureWorks].[Person].[Contact]
  WHERE ContactID IN 

  (SELECT EmployeeID
  FROM [AdventureWorks].[HumanResources].[Employee]
  WHERE SickLeaveHours>68)

結(jié)果如下:

上面的查詢中,在IN關(guān)鍵字后面的子查詢返回一列值作為外部查詢選擇條件使用.

同樣的,與IN關(guān)鍵字的邏輯取反的NOT IN關(guān)鍵字,這里就不再闡述了

但是要強調(diào)的是,不要用IN和NOT IN關(guān)鍵字,這會引起很多潛在的問題,這篇文章對這個問題有著很好的闡述:http://wiki.lessthandot.com/index.php/Subquery_typo_with_using_in。這篇文章的觀點是永遠不要再用IN和NOT IN關(guān)鍵字,我的觀點是存在即合理,我認為只有在IN里面是固定值的時候才可以用IN和NOT IN,比如:

SELECT [FirstName]
      ,[MiddleName]
      ,[LastName]
  FROM [AdventureWorks].[Person].[Contact]
  WHERE ContactID  IN (25,33)

只有在上面這種情況下,使用IN和NOT IN關(guān)鍵字才是安全的,其他情況下,最好使用EXISTS,NOT EXISTS,JOIN關(guān)鍵字來進行替代. 除了IN之外,用于選擇條件的關(guān)鍵字還有ANYALL,這兩個關(guān)鍵字和其字面意思一樣. 和"<",">",”="連接使用,比如上面用IN的那個子查詢:

我想取得總共請病假天數(shù)大于68小時的員工

用ANY關(guān)鍵字進行等效的查詢?yōu)?

SELECT [FirstName]
      ,[MiddleName]
      ,[LastName]
  FROM [AdventureWorks].[Person].[Contact]
  WHERE ContactID =ANY

  (SELECT EmployeeID
  FROM [AdventureWorks].[HumanResources].[Employee]
  WHERE SickLeaveHours>68)

在作為ANY和ALL關(guān)鍵字在子查詢中使用時,所實現(xiàn)的效果如下

=ANY 和IN等價
<>ALL 和NOT IN等價
>ANY 大于最小的(>MIN)
<ANY 小于最大的(<MAX)
>ALL 大于最大的(>MAX)
<ALL 小于最小的(<MIN)
=ALL 下面說

=ALL關(guān)鍵字很少使用,這個的效果在子查詢中為如果只有一個返回值,則和“=”相等,而如果有多個返回值,結(jié)果為空

這里要注意,SQL是一種很靈活的語言,就像子查詢所實現(xiàn)的效果可以使用JOIN來實現(xiàn)一樣(效果一樣,實現(xiàn)思路不同),ANY和ALL所實現(xiàn)的效果也完全可以使用其他方式來替代,按照上面表格所示,>ANY和>MIN完全等價,比如下面兩個查詢語句完全等價:

SELECT *
FROM AdventureWorks.HumanResources.Employee
WHERE SickLeaveHours>ANY

(SELECT SickLeaveHours FROM AdventureWorks.HumanResources.Employee WHERE SickLeaveHours>68)


SELECT *
FROM AdventureWorks.HumanResources.Employee
WHERE SickLeaveHours>

(SELECT MIN(SickLeaveHours) FROM AdventureWorks.HumanResources.Employee WHERE SickLeaveHours>68)

相關(guān)子查詢和EXISTS關(guān)鍵字

前面所說的查詢都是無關(guān)子查詢(Uncorrelated subquery),子查詢中還有一類很重要的查詢是相關(guān)子查詢(Correlated subquery),也叫重復子查詢比如,還是上面那個查詢,用相關(guān)子查詢來寫:

我想取得總共請病假天數(shù)大于68天的員工:

SELECT [FirstName]
      ,[MiddleName]
      ,[LastName]
  FROM [AdventureWorks].[Person].[Contact] c
  WHERE EXISTS

  (SELECT *
  FROM [AdventureWorks].[HumanResources].[Employee] e
  WHERE c.ContactID=e.ContactID AND e.SickLeaveHours>68)

結(jié)果和使用IN關(guān)鍵字的查詢結(jié)果相同:

如何區(qū)別相關(guān)子查詢無關(guān)子查詢呢?最簡單的辦法就是直接看子查詢本身能否執(zhí)行,比如上面的例子中的子查詢

(SELECT *
  FROM [AdventureWorks].[HumanResources].[Employee] e
  WHERE c.ContactID=e.ContactID AND e.SickLeaveHours>68)

這一句本身執(zhí)行本身會報錯.因為這句引用到了外部查詢的表

對于無關(guān)子查詢來說,整個查詢的過程為子查詢只執(zhí)行一次,然后交給外部查詢,比如:

SELECT *
FROM AdventureWorks.HumanResources.Employee
WHERE SickLeaveHours>ANY

SQLRESULT

上面的無關(guān)子查詢,整個查詢過程可以看作是子查詢首先返回SQLResult(SQL結(jié)果集),然后交給外部查詢使用,整個過程子查詢只執(zhí)行一次

而相反,作為相關(guān)子查詢,子查詢的執(zhí)行的次數(shù)依賴于外部查詢,外部查詢每執(zhí)行一行,子查詢執(zhí)行一次,比如:

還是上面的例子:我想取得總共請病假天數(shù)大于68天的員工

SELECT [FirstName]
      ,[MiddleName]
      ,[LastName]
  FROM [AdventureWorks].[Person].[Contact] c
  WHERE EXISTS

  (SELECT *
  FROM [AdventureWorks].[HumanResources].[Employee] e
  WHERE c.ContactID=e.ContactID AND e.SickLeaveHours>68)

----
step 1:
SELECT [FirstName]
      ,[MiddleName]
      ,[LastName]
  FROM [AdventureWorks].[Person].[Contact] c
  WHERE EXISTS

  (SELECT *
  FROM [AdventureWorks].[HumanResources].[Employee] e
  WHERE 1=e.ContactID AND e.SickLeaveHours>68)
----
step 2:
SELECT [FirstName]
      ,[MiddleName]
      ,[LastName]
  FROM [AdventureWorks].[Person].[Contact] c
  WHERE EXISTS

  (SELECT *
  FROM [AdventureWorks].[HumanResources].[Employee] e
  WHERE 2=e.ContactID AND e.SickLeaveHours>68)
----
step n:
SELECT [FirstName]
      ,[MiddleName]
      ,[LastName]
  FROM [AdventureWorks].[Person].[Contact] c
  WHERE EXISTS

  (SELECT *
  FROM [AdventureWorks].[HumanResources].[Employee] e
  WHERE n=e.ContactID AND e.SickLeaveHours>68)

如上面代碼所示。上面的相關(guān)子查詢實際上會執(zhí)行N次(N取決與外部查詢的行數(shù)),外部查詢每執(zhí)行一行,都會將對應行所用的參數(shù)傳到子查詢中,如果子查詢有對應值,則返回TRUE(既當前行被選中并在結(jié)果中顯示),如果沒有,則返回FALSE。然后重復執(zhí)行下一行。

子查詢作為計算列使用

子查詢作為計算列使用時,只返回單個值(Scalar) 。用在SELECT語句之后,作為計算列使用。同樣分為相關(guān)子查詢無關(guān)子查詢

相關(guān)子查詢的例子比如:我想取得每件產(chǎn)品的名稱和總共的銷量

SELECT [Name],
      (SELECT COUNT(*) FROM AdventureWorks.Sales.SalesOrderDetail S
      WHERE S.ProductID=P.ProductID) AS SalesAmount
FROM [AdventureWorks].[Production].[Product] P
  

部分結(jié)果如下:

子查詢作為計算列使用時,會針對外部查詢的每一行,返回唯一的值。

同樣的,SQL子查詢都可以使用其他語句達到同樣的效果,上面的語句和如下語句達到同樣的效果:

SELECT P.Name,COUNT(S.ProductID)
FROM [AdventureWorks].[Production].[Product] P 
LEFT JOIN  AdventureWorks.Sales.SalesOrderDetail S
ON S.ProductID=P.ProductID
GROUP BY P.Name
  

子查詢作為計算列且作為無關(guān)子查詢時使用,只會一次性返回但一值,這里就不再闡述了。

小結(jié)

本篇文章通過子查詢的三種不同用途來闡述子查詢。同時,所有的子查詢還可以分為相關(guān)子查詢和無關(guān)子查詢,而子查詢所實現(xiàn)的功能都可以使用連接或者其他方式實現(xiàn)。但一個好的作家應該是掌握豐富的詞匯,而不是僅僅能表達出自己的意思。學會多種SQL查詢方式是學習SQL查詢必經(jīng)之路。

轉(zhuǎn)自:http://www.cnblogs.com/CareySon/archive/2011/07/18/2109406.html

更多:

http://www.360doc.com/content/11/0407/17/5789627_107867377.shtml

http://blog.csdn.net/lihan6415151528/article/details/4466914

總結(jié)

以上是生活随笔為你收集整理的Sql 子查询的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。

如果覺得生活随笔網(wǎng)站內(nèi)容還不錯,歡迎將生活随笔推薦給好友。