你真的會玩SQL嗎?無處不在的子查詢


  

你真的會玩SQL嗎?系列目錄

你真的會玩SQL嗎?之邏輯查詢處理階段

你真的會玩SQL嗎?和平大使 內連接、外連接

你真的會玩SQL嗎?三范式、數據完整性

你真的會玩SQL嗎?查詢指定節點及其所有父節點的方法

你真的會玩SQL嗎?讓人暈頭轉向的三值邏輯

你真的會玩SQL嗎?EXISTS和IN之間的區別

你真的會玩SQL嗎?無處不在的子查詢

你真的會玩SQL嗎?Case也瘋狂

你真的會玩SQL嗎?表表達式,排名函數

你真的會玩SQL嗎?簡單的 數據修改

你真的會玩SQL嗎?你所不知道的 數據聚合

你真的會玩SQL嗎?透視轉換的藝術

你真的會玩SQL嗎?冷落的Top和Apply

你真的會玩SQL嗎?實用函數方法匯總

你真的會玩SQL嗎?玩爆你的數據報表之存儲過程編寫(上)

你真的會玩SQL嗎?玩爆你的數據報表之存儲過程編寫(下)

 

子查詢又稱內部,而包含子查詢的語句稱之外部查詢(又稱主查詢)。
所有的子查詢可以分為兩類,即相關子查詢和非相關子查詢
1> 非相關子查詢是獨立於外部查詢的子查詢,子查詢總共執行一次,執行完畢后將值傳遞給外部查詢。
2> 相關子查詢的執行依賴於外部查詢的數據,外部查詢執行一行,子查詢就執行一次。
故非相關子查詢比相關子查詢效率高

--非相關子查詢
SELECT EMPNO, LASTNAME
    FROM EMPLOYEE
    WHERE WORKDEPT = 'A00'
     AND SALARY > (SELECT AVG(SALARY)
              FROM EMPLOYEE
              WHERE WORKDEPT = 'A00')

--相關子查詢
SELECT E1.EMPNO, E1.LASTNAME, E1.WORKDEPT
    FROM EMPLOYEE E1
    WHERE SALARY > (SELECT AVG(SALARY)
              FROM EMPLOYEE E2
              WHERE E2.WORKDEPT = E1.WORKDEPT)
    ORDER BY E1.WORKDEPT 
 

 子查詢

 

 

嵌套子查詢,非相關子查詢   

相關例子 相關子查詢和嵌套子查詢 [SQL Server]

 

相關子查詢

 

自聯接

聯合查詢

•Union 操作符:將兩個或更多個 SELECT 語句的結果合並為一個結果集。
•聯合可以指定為如下形式:

     SELECT 語句    UNION [ALL]           SELECT 語句

使用 ALL 子句表示不刪除重復的行

 聯合查詢注意事項:

  1. 每個select必須具有相同的列結構
  2. 兼容列類型(指優先級較低數據類型必須能隱式地轉換為較高級的數據類型)和相同數目的列

 

練習:

使用子查詢

/*1:寫一條查詢語句,返回Orders表中活動的最后一天生成的所有訂單。
涉及的表:Sales.Orders表。
期望的輸出:*/
orderid     orderdate               custid      empid
----------- ----------------------- ----------- -----------
11077       2008-05-06 00:00:00.000 65          1
11076       2008-05-06 00:00:00.000 9           4
11075       2008-05-06 00:00:00.000 68          8
11074       2008-05-06 00:00:00.000 73          7

參考SQL:

--answer:
select orderid,orderdate,custid,empid
from Sales.Orders
where orderdate in (
select max(orderdate) from Sales.Orders
)
/*
1.處理嵌套在外層查詢語句里的子查詢,應用max函數從表Sales.Orders中查找orderdate最后一天的日期,生成虛擬表VT1,
2.處理嵌套在外層的查詢語句,從Sales.Orders表中查找滿足where條件orderdate在虛擬表VT1中有相等值的數據,得到虛擬表VT2
3.處理select列表,從虛擬表VT2中查找出custid,orderdate,custid,empid返回虛擬表VT3
*/
View Code
/*2:寫一條查詢語句,並返回2008年5月1號(包括這一天)以后沒有處理過的訂單的雇員。
涉及到表:HR.Employees表和Sales.Orders表。
期望的輸出:*/
empid       FirstName  lastname
----------- ---------- --------------------
3           Judy       Lew
5           Sven       Buck
6           Paul       Suurs
9           Zoya       Dolgopyatova

參考SQL:

--answer:
select empid,firstname,lastname
from HR.Employees 
where empid not in(
select o.empid
from Sales.Orders as o
where o.orderdate>='2008-05-01'
)

/*
1.處理嵌套在外層查詢語句里的子查詢,表Sales.Orders別名o
2.查找滿足where條件 o.orderdate>='2008-05-01',生成虛擬表VT1
3.從虛擬表VT1中處理select列表,查找出empid生成虛擬表VT2
4.處理嵌套在外層的查詢語句,從Sales.Orders表中查找滿足where條件empid不在虛擬表VT2中有相等值的數據,得到虛擬表VT3
5.處理select列表從虛擬表VT3中查找empid,firstname,lastname返回虛擬表VT4
*/
View Code
/*3:寫一條查詢語句,返回訂購了第12號產品的客戶。
涉及的表:Sales.Customers表和Sales.Orders表。
期望的輸出:*/
custid      companyname
----------------------------------------
48          Customer DVFMB
39          Customer GLLAG
71          Customer LCOUJ
65          Customer NYUHS
44          Customer OXFRU
51          Customer PVDZC
86          Customer SNXOJ
20          Customer THHDP
90          Customer XBBVR
46          Customer XPNIK
31          Customer YJCBX
87          Customer ZHYOS

參考SQL:

--answer:
SELECT custid, companyname
FROM Sales.Customers AS C
WHERE EXISTS
  (SELECT *
   FROM Sales.Orders AS O
   WHERE O.custid = C.custid
     AND EXISTS
       (SELECT *
        FROM Sales.OrderDetails AS OD
        WHERE OD.orderid = O.orderid
          AND OD.ProductID = 12));
/*
1.先處理外層查詢,從Sales.Customers表別名C中取出一個元組,將元組相關列值custid傳給內層查詢
2.執行第一層內層查詢,Sales.Orders表別名O中取出一個元組,將元組相關列值custid傳給內層查詢
3.執行第二層內層查詢,Sales.Orders表別名OD應用where子句返回滿足條件OD.orderid = O.orderid和 OD.ProductID = 12的值
4.返回到第一層內層查詢中,應用where子句返回滿足條件O.custid = C.custid和EXISTS條件的值
5.返回到外層查詢處理 EXISTS,外查詢根據子查詢返回的結果集得到滿足條件的行
*/
View Code

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM