1 小時 SQL 極速入門(一)

李英傑同學發表於2018-11-22

前幾天,我在論壇溜達。看到一個人發帖說

做了6年的企業級開發,總是被網際網路行業的人認為沒技術含量,不就是CRUD麼 先解釋下 CRUD 是什麼。CRUD 就是我們常說的增刪改查(Create,Retrieve,Update,Delete)

其實,對這個問題,我也思考過。我們所有的業務流程,最終都會抽象出資料模型,儲存到資料庫中。把業務之間的聯絡抽象成資料庫中表與表,欄位與欄位之間的聯絡。實際上,企業的各種系統,在技術層面上確實是在 CRUD。

不過話說回來了,網際網路的系統不是 CRUD 嗎?只不過 CRUD 的姿勢不同罷了,網際網路可能是面對高併發的 CRUD, 我們是面對的是複雜業務流程的 CRUD。這些業務邏輯還需要一定的行業積澱才能捋清楚。所以在企業級開發上業務和技術基本是五五開,業務比重甚至要大於技術。

所以,今天我們就花很短的時間,來學學簡單的 SQL.瞭解下 CRUD 的姿勢。 假如我們有下面一個訂單表 ORDER_HEADER,不要在意表裡的資料,為了方便說明,瞎填的。

ORDER_HEADER.png

查詢

查詢是我們平日使用最多的,下面著重說一下: 查詢使用 SELECT 關鍵字,基本結構如下

SELECT <列名> FROM <表名> WHERE <條件>

假如我們想查詢所有已經完工的訂單資訊,那麼 SQL 怎麼寫呢?

SELECT * FROM order_header WHERE order_status = '完工'
複製程式碼

執行後會看到我們需要的結果

SELECT.png

SELECT * 代表查詢所有列,一般我們會關注我們需要的欄位,比如我們要找到訂單型別為 1 的並且完工的訂單號,我們可以這麼寫

SELECT order_no FROM order_header WHERE order_status = '完工' AND order_type = 1
複製程式碼

我們可以看到只有下面兩個符合條件的訂單號被選中。在寫 SQL 中我們要儘量避免 SELECT * ,我們需要哪個欄位就取哪個欄位,可以節省 SQL 查詢的時間。

SELECT1.png

如果要查詢訂單型別為 1 的或者處於下達狀態的訂單,SQL 怎麼寫呢?

SELECT order_no FROM order_header WHERE order_type = 1 OR order_status = '下達'
複製程式碼

如果要查詢開工,下達和完工狀態的訂單,我們可以用 IN 關鍵字

SELECT
    order_no,
    order_type,
    order_status
FROM
    order_header
WHERE
    order_status IN ( '開工', '完工', '下達' )
複製程式碼

除了 IN 我們可以使用 LIKE 進行模糊查詢,比如我們要查詢訂單狀態中包含 “工” 的所有訂單

SELECT order_no FROM order_header WHERE  order_status LIKE '%工%'
複製程式碼

這裡的 "%" 表示萬用字元,"%工"表示以工結尾的所有匹配,"工%"表示以工開頭的所有匹配。 此外,我們可以用 NOT IN , NOT LIKE 來取相反的邏輯。

通過 GROUP BY 可以進行分組,比如我們按照訂單狀態來分組,就可以很方便的檢視當前有幾種狀態的訂單

SELECT order_status FROM order_header GROUP BY order_status
複製程式碼

結果如下圖

GROUP.png

如果我們想看到每個分組中有多少訂單,那個我們可以使用 COUNT() 函式

SELECT order_status, COUNT(1) FROM order_header GROUP BY order_status
複製程式碼

結果如下圖,可以看到每個分組中訂單的數量。除了COUNT(),還有 MAX(),MIN(),SUM()等函式

COUNT.png

如果我們只想看到數量大於 2 的分組,該怎麼寫?

SELECT order_status, COUNT(1) FROM order_header GROUP BY order_status HAVING COUNT(1) > 2
複製程式碼

可以看到,只有數量大於2的分組被查到了。

HAVING.png

如果僅僅想去重,比如想知道總共有幾種訂單型別,那麼我們只需要對此列用 DISTINCT 即可。

SELECT DISTINCT order_type FROM order_header
複製程式碼

結果中的訂單型別列已經被去重了。

DISTINCT.png

CASE WHEN ,有時我們會需要簡單的判斷邏輯,就可以用 CASE WHEN 了。比如我們想讓 訂單型別為1 的表示生產訂單,訂單型別為2 的表示更改訂單,訂單型別為3 的表示廢棄訂單。那麼我們可以這麼寫

SELECT
    order_no,
    order_type,
    order_status,
CASE
    WHEN order_type = 1 THEN '生產訂單'
    WHEN order_type = 2 THEN '更改訂單'
    WHEN order_type = 3 THEN '廢棄訂單'
    ELSE '未知型別'
    END AS type_desc
FROM
order_header
複製程式碼

結果如下圖

CASEWHEN.png

子查詢,有時候我們需要從一個結果集中再次查詢,就會用到子查詢。比如下面這樣寫

SELECT
    order_no,
    type_desc
FROM
    (
SELECT
    order_no,
    order_type,
    order_status,
CASE
    WHEN order_type = 1 THEN '生產訂單'
    WHEN order_type = 2 THEN '更改訂單'
    WHEN order_type = 3 THEN '廢棄訂單'
    ELSE '未知型別'
    END AS type_desc
FROM
    order_header
) t
複製程式碼

下節課我們說一下 連線查詢和常用到的分析函式,在企業中,單表查詢情況是很少的,要關聯查詢。

插入資料

插入資料我們使用 INSERT 語句

INSERT INTO order_header ( order_no, order_type, order_status, order_date, createdon )
VALUES
    ( '2018102109', 2, '下達', sysdate( ), sysdate( ) )
複製程式碼

看到,最下面就是我們新插入的一行

INSERT.png

更新資料

更新資料使用 UPDATE 語句,我們更新一下剛才插入的資料的訂單號

UPDATE order_header SET order_no = '112109' WHERE order_no = '2018102109'
複製程式碼

我們把 訂單號為'2018102109'的一行資料更新為了'112109',在update時一定要寫好 WHERE 條件,如果沒有 WHERE 條件,會更新表中所有資料。

刪除資料

我們刪除剛才加入的一條資料

DELETE FROM order_header WHERE order_no = '112109'
複製程式碼

執行後,訂單號為'112109'的訂單就被刪除了,DELETE 時同樣要寫好 WHERE 條件,如果沒有 WHERE 條件,會刪除表中所有資料。

下節重點說說 多表連線,常用分析函式。不要走開哦。

相關文章