在上回 [Day10] SQL server Select合併查詢JOIN用法 - SQL Server資料庫入門 中,我們練習了合併查詢的JOIN。
在這回中,我們主要淺談一下子查詢。
他跟JOIN一樣都可以使用在多表的查詢上。
子查詢
子查詢通常使用在Select的Where子句上。
首先處理的是子查詢條件,才會向外處理外部的主查詢。有點像是寫一個function,然後回傳一個結果再給主程式去跑。
語法:
1 | SELECT 欄位名稱1,欄位名稱2,...,欄位名稱n |
1.子查詢要在括號()中。
2.通常子查詢SELECT只會取得單一欄位的值,以便主查詢的欄位進行比較運算。
3.如需排序,子查詢不能使用ORDER BY,只能使用GROUP BY 子句。
4.如果子查詢可以取得多筆資料,在主查詢需使用IN邏輯運算子。
在WHERE使用子查詢主要目的是取得其他資料表紀錄的欄位值來建立WHERE句的條件運算式。
實際演練
目前表中資料
在此,提供一下目前資料表中的測試資料,作為核對。
customers 顧客
products 產品
orders 出貨單
order_details 出貨單明細
實作:想要取得名子為XXX的訂單。
1 | Select * from orders |
結果:
子查詢的語句只會返回單一一筆的number叫做U001,之後就會變成orders.customer_number = ‘U001’去搜尋,最後得到結果。
實作:想要取得大於平均值的商品列表。
1 | Select *,(select avg(price) from products) as avg_price from products |
結果:
原本想要寫成 where price > avg_price,但發現這樣的寫法不可以,因為前面的這種匿名欄位(原本就不在資料表中的欄位)在where後沒辦法取得,所以又補了一段(select avg(price) from products)。
總之,子查詢也可以用在欄位上。
實作:想取得訂單明細中有商品PS4及PS5的明細。
[補充]EXISTS指令:可以判斷子查詢的結果有沒有回傳資料,若有則會執行查詢中的結果。
1 | Select * from order_details |
結果:
搜尋order_details表單後用Exists子查詢,用Select取出商品名稱為PS4或PS5的集合,並且這集合的產品編號在訂單明細的產品編號裡。
實作:想取得還沒有下過訂單的顧客。
[補充]IN指令可以檢查是否存在子查詢的資料紀錄中。
1 | Select * from customers |
結果:
用子查詢去查orders資料表,得到客戶編號的集合。之後主查詢用not in去篩選不在集合中的顧客編號。
最終得到U002這個沒下訂單的顧客。
小結
在這篇中練習了子查詢的寫法,並且知道子查詢可以放在欄位、或where後,且可以搭配如exists、in等等做法去擴展用法。
可能會找一時間把一些擴展語法如exists、in等等類型的都拉出來獨立講一遍。
下篇預計會是垂直的UNION查詢的做法。