你真的會玩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
所有的子查詢可以分為兩類,即相關子查詢和非相關子查詢
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
子查詢
嵌套子查詢,非相關子查詢
相關子查詢
自聯接
聯合查詢
•Union 操作符:將兩個或更多個 SELECT 語句的結果合並為一個結果集。
•聯合可以指定為如下形式:
SELECT 語句 UNION [ALL] SELECT 語句
使用 ALL 子句表示不刪除重復的行。

聯合查詢注意事項:
- 每個select必須具有相同的列結構
- 兼容列類型(指優先級較低數據類型必須能隱式地轉換為較高級的數據類型)和相同數目的列
練習:
使用子查詢
/*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 */
/*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 */
/*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,外查詢根據子查詢返回的結果集得到滿足條件的行 */