最近作數據上報的報表,發現一些基礎的SQL模糊不清了,這裏持續記錄使用到的SQL操做。html
基本的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
FROM <left_table> <join_type> JOIN <right_table> ON <join_condition>
,對兩張表根據ON
操做符指定的關聯條件,合併成一個臨時表A。
<join_type>
包括:INNER JOIN
、Full outer join
、LEFT OUTER JOIN
、RIGHT OUTER JOIN
、CROSS JOIN
。數據庫
INNER JOIN
表示合併的臨時表A中,僅包含符合ON
條件的記錄。LEFT OUTER JOIN
表示合併的臨時表A中,不只包含符合ON
條件的記錄,還會把left_table
中剩餘的記錄也保存在臨時表,同時將對應的right_table
中的全部列字段賦值爲NULL。RIGHT OUTER JOIN
表示合併的臨時表A中,不只包含符合ON
條件的記錄,還會把right_table
中剩餘的記錄也保存在臨時表A,同時將對應的left_table
中的全部列字段賦值爲NULL。Full outer join
表示合併的臨時表A中,不只包含符合ON
條件的記錄,還會把left_table
和right_table
中剩餘的記錄也保存在臨時表A,同時將對應的另一張表的列字段賦值爲NULL。其實就是兩張表的交集。CROSS JOIN
表示兩張表的笛卡爾積,通常不多使用。
關於JOIN
的各類使用,能夠參考圖解SQL的JOIN
WHERE <where_condition>
指定的過濾條件,刪除一些不符合條件的記錄,獲得臨時表B。GROUP BY <group_by_list>
指定的列字段,進行分組操做。而後根據HAVING <having_condition>
指定的條件對分組進行過濾,獲得臨時表C。這裏HAVING指定的條件只能包含分組字段,或者其餘列字段的聚合函數。SELECT DISTINCT <select_list>
規定的字段,選出僅包含指定列字段的臨時表D,若是指定了DISTINCT
,那麼還要把重複的行記錄過濾掉。ORDER BY <order_by_condition>
指定的列字段,對臨時表D的全部行記錄進行排序,獲得臨時表E。LIMIT <limit_number>
指定的條件,從臨時表E中,摘錄出指定數量的行記錄,生成最終的結果表。limit的用法是:limit n,m,表示從第n條記錄開始選擇m條記錄。通常可用於列表分頁,對於小數據,使用limit沒有任何問題。可是當數據量很是大的時候,使用limit是很是低效的。由於limit的機制是每次都從頭開始掃描,若是須要從第50萬行開始,讀取10條數據,那麼就須要先掃描定位到第50萬行,而後再讀取10條記錄,而掃描是一個很是低效的過程。複製代碼
通常狀況下,基本的SQL語句均可以按照上面6個步驟進行分析。bash
上面介紹了基本SQL語句的內部執行順序,下面咱們看一些經常使用的SQL函數,這些函數的使用能幫助咱們解決一些複雜的SQL問題。函數
Case When Then
Case函數很像if else
語句,能夠進行多條件判斷。Case具備兩種格式:簡單Case函數和Case搜索函數。ui
CASE sex
WHEN '1' THEN '男'
WHEN '2' THEN '女'
ELSE '其餘' END複製代碼
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 |
後續使用到繼續補充...