sql數據分析和使用說明?本篇文章繼續圍繞SQL的語法重點為大家介紹子查詢的使用,下面我們就來說一說關于sql數據分析和使用說明?我們一起去了解并探讨一下這個問題吧!
sql數據分析和使用說明
本篇文章繼續圍繞SQL的語法重點為大家介紹子查詢的使用。
01 子查詢使用子查詢進行過濾
在SQL中SELECT語句用于查詢,之前所使用的所有SELECT語句都是簡單查詢,即從單個數據庫表中檢索數據的單條語句。然而SQL還可以創建子查詢,即嵌套在其他查詢中的查詢。
示例:
數據表:本次使用的數據庫表都是關系表。訂單存儲在兩個表中,每個訂單包含訂單編号、客戶ID、訂單日期,在Orders表中存儲為一行。各訂單的物品存儲在相關的OrderItems表中。Orders表不存儲顧客信息,隻存儲顧客ID。顧客實際信息存儲在Customers表中。
若現在需要檢索出訂購RGAN01的所有顧客,應怎樣檢索?步驟如下:
①檢索包含物品RGAN01的所有訂單的編号。
②檢索具有前一步驟列出的訂單編号的所有顧客的ID。
③檢索前一步驟返回的所有顧客ID的顧客信息。
上述每個步驟都可單獨作為一個查詢來進行。
可将一條SELECT語句返回的結果用于另一條SELECT語句的WHERE子句,也可使用子查詢來将3個查詢組合成一條語句。
①第一個語句含義明确,是對prod_id為RGAN01的所有訂單物品檢索其order_num列。
示例:
SELECT order_num
FROM OrderItems
WHERE prod_id = ‘RGAN01’
分析:通過該語句知道了哪個訂單包含要檢索的物品。
②下一步查詢與上述語句檢索出的訂單20007和20008相關的顧客ID。此處可利用IN子句。
示例:
SELECT cust_id
FROM Orders
WHERE order_num IN (20007,20008)
下面可結合上述兩個查詢,将第一個查詢變為子查詢。
示例:
SELECT cust_id
FROM Orders
WHERE order_num IN
(SELECT order_num
FROM OrderItems
WHERE prod_id = ‘RGAN01’)
分析:在SELECT語句中,子查詢總是從内向外處理。在處理上述SELECT語句時,DBMS實際上執行了兩個操作。
首先執行了圓括号()内的查詢,此查詢返回兩個訂單号:20007和20008.
接着這兩個值以IN操作符要求的逗号分隔的格式傳遞給外部查詢的WHERE子句。外部查詢變為:
SELECT cust_id
FROM orders
WHERE order_num IN (20007,20008)
該語句檢索的結果和前面硬編碼WHERE子句返回的結果相同。
③由上述語句得出訂購物品RGAN01的所有顧客ID:100004和100005.下一步檢索這些顧客ID的顧客信息。
示例:
SELECT cust_name,cust_contact
FROM Customers
WHERE cust_id IN (100004,100005)
也可将其中的WHERE子句轉換為子查詢,就不用硬編碼這些顧客ID了。
示例:
SELECT cust_name,
cust_contace
FROM Customers
WHERE cust_id IN
(SELECT cust_id
FROM Orders
WHERE order_num IN
(SELECT order_num
FROM OrderItems
WHERE prod_id = ‘RGAN01’))
分析:DBMS實際上必須執行三條SELECT語句才能完成上述語句。最裡面的子查詢返回訂單号,此列用于外面的子查詢的WHERE子句。外面的子查詢返回顧客ID列,此顧客ID列用于最外層查詢的WHERE子句。最外層查詢返回最終所需的數據。
由此可見,在WHERE子句中使用子查詢可編寫出功能強大靈活的SQL語句。對于能嵌套的子查詢的數目沒有限制,不過在實際應用中由于性能的限制,不宜嵌套太多子查詢。
注意:作為子查詢的SELECT語句隻能查詢單個列,檢索多個列将返回錯誤。另外使用子查詢并不總是執行該類數據檢索的最有效方法。
不止SQL數據庫學習,還有全面的大數據分析學習
TopBDA大數據分析師培訓
作為計算字段使用子查詢
使用子查詢的另一方法是創建計算字段。
示例:需要顯示Customers表中每個顧客的訂單總數。訂單與相應的顧客ID都存儲在Orders表中。要執行這個操作,需要以下步驟:
①從Customers表中檢索顧客列表。
②對于檢索出的每個顧客,統計其在Orders表中的訂單數目。
這裡我們可以應用之前介紹的SELECT COUNT(*)對表中的行進行計數,并通過一條WHERE子句來過濾某個特定的顧客ID,僅對該顧客的訂單進行計數。
如下對顧客1000001的訂單進行計數:
SELECT COUNT(*) AS orders
FROM Orders
WHERE cust_id = 1000001
要對每個顧客執行COUNT(*)需要将其作為一個子查詢,如下:
SELECT cust_name,
cust_state,
(SELECT COUNT(*)
FROM Orders
WHERE Orders.cust_id = Customers.cust_id) AS orders
FROM Customers
ORDER BY cust_name
分析:該SELECT語句對Customers表中的每個顧客返回三列:cust_name、cust_state和orders。orders是一個計算字段,它由圓括号中的子查詢建立。該子查詢對檢索出的每個顧客執行一次。此例中,該子查詢執行了5次,因為檢索出了5個顧客。
子查詢中的WHERE子句與之前使用的WHERE子句略有不同,因為它使用了完全限定列名,而不隻是列名(cust_id)。它指定表名和列名(Orders.cust_id和Customers.cust_id)。下面的WHERE子句告訴SQL,比較Orders表中的cust_id和當前正從Customers表中檢索出的cust_id:
WHERE Orders.cust_id = Customers.cust_id
在有可能混淆列名時必須用一個句點分隔表名和列名。此例中,有兩個cust_id列:一個在Customers中,另一個在Orders中。若不采用完全限定名,DBMS會認為要對Orders表中的cust_id自身進行比較。因為:
SELECT COUNT(*)
FROM Orders
WHERE cust_id =cust_id
上述語句總返回Orders表中訂單的總數,而該結果不是我們想要的,如下:
SELECT cust_name,
cust_state,
(SELECT COUNT(*)
FROM Orders
WHERE cust_id = cust_id) AS orders
FROM Customers
ORDER BY cust_name
由上可知,在構造語句時,若涉及到多個表,而不對同一列名加以區分則會引起DBMS抛出錯誤信息。
好的做法是,當在SELECT語句中操作多個表時,使用完全限定列名來避免歧義。
最後總結一下子查詢的特點:
①子查詢必須括在圓括号中。
②子查詢的SELECT子句中隻能有一個列,除非主查詢中有多個列,用于與子查詢選中的列相比較。
③子查詢不能使用ORDER BY,不過主查詢可以。在子查詢中,GROUP BY可以起到同ORDER BY相同的作用。
④返回多行數據的子查詢隻能同多值操作符一起使用,比如IN操作符。
⑤SELECT 列表中不能包含任何對BLOB、ARRAY、CLOB或者NCLOB類型值的引用。
⑥子查詢不能直接用在聚合函數中。
⑦BETWEEN操作符不能同子查詢一起使用,但是BETWEEN操作符可以用在子查詢中。
以上便是本次介紹的全部内容,下篇文章将為大家講解連接和高級連接的使用。
我們下期再見!
,