版權聲明

本文首發於微信公眾號

這樣和數據相處(data_gentleman)

無需授權即可轉載 轉載時請註明出處

我們都知道,作為一名數據分析師,熟練使用資料庫是必備技能之一。

因為它在我們統計數據、提取數據、數據共享等方面有著至關重要的作用。

同時,我們在實際的使用過程中,又有至少90%的SQL語句是屬於數據操作語言(Data Manipulation Language)範疇。

而在這90%的語句中,我們在絕大多數情況會用到的,要非Select語句莫屬了。

可能你會說,Select語句還不簡單?我會用。

其實不用你說,我們都知道,一條完整select語句非常簡單,無非是:

select <欄位>
from <表名>
join <表名> on <條件>
where <條件>
group by <主鍵>
having <條件> # 給組添加條件
order by <排序>
limit <常數>

而這條語句執行的邏輯,也無非是:

from -> on -> join -> where -> group by -> having -> select -> order by -> limit

很簡單嘛。

是的,一條語句當然簡單。但是我們在實際運用中,可不僅僅使用一條selec語句就足夠了。我們通常會嵌套其他子查詢或聚合函數等語句一起使用。也就是我們經常說的高級查詢了。

如果你能恰當的使用它的話,就可以寫出更加靈活的SQL了。

在這之前,我們先來講一個新的工具——視圖

視圖

從SQL角度來說,視圖和表的意義是相同的。只不過表儲存的是實際的數據,而視圖中保存的是select語句。即視圖本身不存儲數據,它保存的僅是select語句。

你可以將視圖理解成用select語句寫的一個臨時表,只具備讀取數據的功能,並不會將結果數據添加到也數據表中。

總體來說,視圖有兩大優點:

  1. 節省存儲設備的容量,因為視圖無需保存數據。
  2. 可以將頻繁使用的select語句保存成視圖,避免每次都重複書寫。

而我們創建視圖需要使用create view語句來實現:

# <>」符號請忽略
create view 視圖名稱(<視圖列名1>, <視圖列名2>, ……)
as
<select語句>

在我們創建視圖之後,就可以直接通過設置的視圖名稱來調用它,而後直接嵌入一個新的select語句中。非常之方便。比如:

# 定義視圖
create view product_sum(product_type, sum_price)
as
select product_type, sum(price)
from product
group by product_type;

# 調用視圖
select product_type, sum_price
from product_sum

但同時,我們也要注意,視圖也不是隨隨便便就能設置的,它也有自己的脾氣:

  1. 定義視圖不能使用order by語句。
  2. 通過group by語句對原表進行分組統計得到的是同,不能直接進行更新。需要對視圖和原表同時進行更新。
  3. 要儘可能避免在視圖的基礎上再次創建視圖喲,雖然語法並不會報錯

接著,我們刪除視圖的時候,可以直接用drop語句:

# 刪除視圖
drop view 視圖名稱

對了,我們構建了多個視圖後可以調用join來將含有共同欄位的視圖聯合在一起喲。

好,視圖的部分講完了。接下來,我們來聊聊與視圖緊密相關的子查詢。

子查詢

如果說我們定義了視圖之後,在後面的語句中可以直接調用,那麼子查詢就相當於一次性視圖。即它在select語句執行完畢之後就會消失。

但是,子查詢仍可直接運用於from子句當中,實現與視圖相同的效果。(請自行對比上面的視圖調用舉例喲)

# from子句中直接嵌套子查詢
select product_type, sum_product
from (select product_type, sum(price) as sum_product
from product
group by prodcut_type) as product_sum;

看吧,子查詢能實現和視圖一樣的效果。不同的是,「product_sum」雖然是該子查詢的名字(有時,前面的as關鍵字也可省略),但在這條select語句執行之後就會消失。

從理論上來講,子查詢的層數是沒有限制的。因此,你可以在某子查詢的from子句中,繼續使用子查詢,該子查詢的from子句中還可再次使用子查詢……無限循環下去。

值得注意的是,雖然子查詢與select語句一樣,都是查詢語句,但因為前者在from子句中,因為會優先該子查詢,而後才是外層的select語句。

最後,我們來談一談關聯子查詢。

關聯子查詢

關聯子查詢主要是在細分的組內數據進行分組比較時使用。

換句話說,就是在子查詢中給數據分組時,因為子查詢返回的結果必須是單一數值,所以語句會報錯。這個時候,就要考慮用到關聯子查詢。例如:

# 報錯的分組子查詢
select product_type, product_name, sale_price
from product
where sale_price > (select avg(sale_price)
from product
group by product_type);

# 改用關聯子查詢,成功執行
select product_type, product_name, sale_price
from product as pt1
where sale_price > (select avg(sale_price)
from product as pt2
where pt1.product_type = pt2.product_type
group by product_type); # 這句可以省略,因為該where條件已經按種類進行了均值計算

從另一個角度來說,上面的關聯子查詢,和group by語句一樣,可以用來對數據進行切分。只不過關聯子查詢只能返回一個結果。

但要注意的是,在使用關聯子查詢的時候,數據與數據之間的結合條件必須寫在內層子查詢中。

最後的最後,來總結一下全文:

  1. 簡單的查詢並不能滿足工作的實際需要,因此我們需要熟練掌握高級的查詢技巧。
  2. 視圖的本質是一個有名字查詢語言,只不過這個名字在不刪除前可以一直使用。
  3. 子查詢是一次性的視圖,因此它的名字在select語句結束後會消失。通常用在from子句後面,且可以無限嵌套。
  4. 視圖可以嵌套join語句,子查詢也可以。
  5. 關聯子查詢主要是在細分的組內數據進行分組比較時使用。

以上,就是本文的全部內容,大部分SQL語言均可通用。

如果你想關注更多關於數據分析師處理數據、工具使用技巧方面的知識,歡迎掃描下方二維碼關注我喲~

weixin.qq.com/r/ADhaQob (二維碼自動識別)


推薦閱讀:
相关文章