重拾Sql語句

最近作數據上報的報表,發現一些基礎的SQL模糊不清了,這裏持續記錄使用到的SQL操做。html

基礎的SQL

基本的SQL語句能夠歸納爲如下僞代碼:sql

SELECT 
DISTINCT <select_list> 
FROM <left_table> 
<join_type> JOIN <right_table> 
ON <join_condition> 
WHERE <where_condition> 
GROUP BY <group_by_list> 
HAVING <having_condition> 
ORDER BY <order_by_condition> 
LIMIT <limit_number>複製代碼

搞清楚上面各個僞代碼的執行順序,對咱們寫SQL有很大的幫助:shell

  1. 首先是處理FROM <left_table> <join_type> JOIN <right_table> ON <join_condition>,對兩張表根據ON操做符指定的關聯條件,合併成一個臨時表A。

    <join_type>包括:INNER JOINFull outer joinLEFT OUTER JOINRIGHT OUTER JOINCROSS JOIN數據庫

    1. INNER JOIN表示合併的臨時表A中,僅包含符合ON條件的記錄。
    2. LEFT OUTER JOIN表示合併的臨時表A中,不只包含符合ON條件的記錄,還會把left_table中剩餘的記錄也保存在臨時表,同時將對應的right_table中的全部列字段賦值爲NULL。
    3. RIGHT OUTER JOIN表示合併的臨時表A中,不只包含符合ON條件的記錄,還會把right_table中剩餘的記錄也保存在臨時表A,同時將對應的left_table中的全部列字段賦值爲NULL。
    4. Full outer join表示合併的臨時表A中,不只包含符合ON條件的記錄,還會把left_tableright_table中剩餘的記錄也保存在臨時表A,同時將對應的另一張表的列字段賦值爲NULL。其實就是兩張表的交集。
    5. CROSS JOIN表示兩張表的笛卡爾積,通常不多使用。
      關於JOIN的各類使用,能夠參考圖解SQL的JOIN
  2. 第一步把兩張表合併到了一張臨時表A,接下來是對臨時表A處理WHERE <where_condition>指定的過濾條件,刪除一些不符合條件的記錄,獲得臨時表B。
  3. 上一步獲得了篩選記錄後的臨時表B,接下來針對臨時表B,根據GROUP BY <group_by_list>指定的列字段,進行分組操做。而後根據HAVING <having_condition>指定的條件對分組進行過濾,獲得臨時表C。這裏HAVING指定的條件只能包含分組字段,或者其餘列字段的聚合函數。
  4. 上一步獲得了分組後的臨時表C,接下來就是根據SELECT DISTINCT <select_list>規定的字段,選出僅包含指定列字段的臨時表D,若是指定了DISTINCT,那麼還要把重複的行記錄過濾掉。
  5. 上一步獲得了篩選列字段後的臨時表D,而後就是根據ORDER BY <order_by_condition>指定的列字段,對臨時表D的全部行記錄進行排序,獲得臨時表E。
  6. 最後,根據LIMIT <limit_number>指定的條件,從臨時表E中,摘錄出指定數量的行記錄,生成最終的結果表。
    limit的用法是:limit n,m,表示從第n條記錄開始選擇m條記錄。通常可用於列表分頁,對於小數據,使用limit沒有任何問題。可是當數據量很是大的時候,使用limit是很是低效的。由於limit的機制是每次都從頭開始掃描,若是須要從第50萬行開始,讀取10條數據,那麼就須要先掃描定位到第50萬行,而後再讀取10條記錄,而掃描是一個很是低效的過程。複製代碼

通常狀況下,基本的SQL語句均可以按照上面6個步驟進行分析。bash

SQL函數

上面介紹了基本SQL語句的內部執行順序,下面咱們看一些經常使用的SQL函數,這些函數的使用能幫助咱們解決一些複雜的SQL問題。函數

Case When Then

Case函數很像if else語句,能夠進行多條件判斷。Case具備兩種格式:簡單Case函數和Case搜索函數。ui

簡單Case函數

CASE sex
    WHEN '1' THEN '男'
    WHEN '2' THEN '女'
ELSE '其餘' END複製代碼

Case搜索函數

CASE WHEN sex = '1' THEN '男'
     WHEN sex = '2' THEN '女'
ELSE '其餘' END

SELECT name, score, 
(CASE WHEN score < 60 THEN '不及格' 
WHEN score BETWEEN 60 AND 90 THEN '良好' 
WHEN score > 90 THEN '優秀' END) as level
FROM student複製代碼

上面兩種方式,能夠實現相同的功能。簡單Case函數的寫法相對比較簡潔,可是和Case搜索函數相比,功能方面會有些限制,好比寫判斷式。spa

具體案例

有以下一個數據庫表,標示了各個國家的人口,要求求出亞洲和美洲的人口總數:
| country | people |
| -------- | :-----: |
| brazil | 100 |
| china | 100 |
| india | 100 |
| mexico | 100 |
| usa | 100 |
| england | 100 |code

咱們只要把屬於亞洲和美洲的國家的人口累加,就能夠了。因此sql語句以下所示:htm

SELECT 
(case country when 'china' then "asia"
             when 'india' then "asia"
             when 'mexico' then "america"
             when 'usa' then "america"
             when 'brazil' then "america"
             else
                "other"
             end) as continent , sum(people) as num FROM leon.TableA
group by
(case country when 'china' then "asia"
             when 'india' then "asia"
             when 'mexico' then "america"
             when 'usa' then "america"
             when 'brazil' then "america"
             else
                "other"
             end);複製代碼

上述SQL語句首先把country分爲亞洲和美洲兩個維度,而後根據這個新維度進行分組,並使用聚合函數,求出各個大洲的總人口。
最後得出的結果表以下所示:
| continent | num |
| -------- | :-----: |
| america | 300 |
| asia | 200 |
| other | 100 |


後續使用到繼續補充...

參考文檔

相關文章
相關標籤/搜索