SQL 語法速成手冊,yyds!

本文針對關係型數據庫的一般語法。限於篇幅,本文側重說明用法,不會展開講解特性、原理。

一、基本概念
數據庫術語

  • 數據庫(database) - 保存有組織的數據的容器(通常是一個文件或一組文件)。
  • 數據表(table) - 某種特定類型數據的結構化清單。
  • 模式(schema) - 關於數據庫和表的佈局及特性的信息。模式定義了數據在表中如何存儲,包含存儲什麼樣的數據,數據如何分解,各部分信息如何命名等信息。數據庫和表都有模式。
  • 列(column) - 表中的一個字段。所有表都是由一個或多個列組成的。
  • 行(row) - 表中的一個記錄。
  • 主鍵(primary key) - 一列(或一組列),其值能夠唯一標識表中每一行。

SQL 語法
SQL(Structured Query Language),標準 SQL 由 ANSI 標準委員會管理,從而稱爲 ANSI SQL。各個 DBMS 都有自己的實現,如 PL/SQL、Transact-SQL 等。

SQL 語法結構

SQL 語法結構包括:

  • 子句 - 是語句和查詢的組成成分。(在某些情況下,這些都是可選的。)
  • 表達式 - 可以產生任何標量值,或由列和行的數據庫表
  • 謂詞 - 給需要評估的 SQL 三值邏輯(3VL)(true/false/unknown)或布爾真值指定條件,並限制語句和查詢的效果,或改變程序流程。
  • 查詢 - 基於特定條件檢索數據。這是 SQL 的一個重要組成部分。
  • 語句 - 可以持久地影響綱要和數據,也可以控制數據庫事務、程序流程、連接、會話或診斷。

SQL 語法要點

  • SQL 語句不區分大小寫,但是數據庫表名、列名和值是否區分,依賴於具體的 DBMS 以及配置。
  • 例如:SELECT 與 select 、Select 是相同的。
  • 多條 SQL 語句必須以分號(;)分隔。
  • 處理 SQL 語句時,所有空格都被忽略。SQL 語句可以寫成一行,也可以分寫爲多行。
-- 一行 SQL 語句
UPDATE user SET username='robot', password='robot' WHERE username = 'root';

-- 多行 SQL 語句
UPDATE user
SET username='robot', password='robot'
WHERE username = 'root';

SQL 支持三種註釋

## 註釋1
-- 註釋2
/* 註釋3 */

SQL 分類
數據定義語言(DDL)
數據定義語言(Data Definition Language,DDL)是 SQL 語言集中負責數據結構定義與數據庫對象定義的語言。

DDL 的主要功能是定義數據庫對象。

DDL 的核心指令是 CREATE、ALTER、DROP。

數據操縱語言(DML)
數據操縱語言(Data Manipulation Language, DML)是用於數據庫操作,對數據庫其中的對象和數據運行訪問工作的編程語句。

DML 的主要功能是 訪問數據,因此其語法都是以讀寫數據庫爲主。

DML 的核心指令是 INSERT、UPDATE、DELETE、SELECT。這四個指令合稱 CRUD(Create, Read, Update, Delete),即增刪改查。

事務控制語言(TCL)
事務控制語言 (Transaction Control Language, TCL) 用於管理數據庫中的事務。這些用於管理由 DML 語句所做的更改。它還允許將語句分組爲邏輯事務。

TCL 的核心指令是 COMMIT、ROLLBACK。

數據控制語言(DCL)
數據控制語言 (Data Control Language, DCL) 是一種可對數據訪問權進行控制的指令,它可以控制特定用戶賬戶對數據表、查看錶、預存程序、用戶自定義函數等數據庫對象的控制權。

DCL 的核心指令是 GRANT、REVOKE。

DCL 以控制用戶的訪問權限爲主,因此其指令做法並不複雜,可利用 DCL 控制的權限有:CONNECT、SELECT、INSERT、UPDATE、DELETE、EXECUTE、USAGE、REFERENCES。

根據不同的 DBMS 以及不同的安全性實體,其支持的權限控制也有所不同。

(以下爲 DML 語句用法)

二、增刪改查
增刪改查,又稱爲 CRUD,數據庫基本操作中的基本操作。

插入數據
INSERT INTO 語句用於向表中插入新記錄。

插入完整的行

INSERT INTO user
VALUES (10, 'root', 'root', '[email protected]');

插入行的一部分

INSERT INTO user(username, password, email)
VALUES ('admin', 'admin', '[email protected]');

插入查詢出來的數據

INSERT INTO user(username)
SELECT name
FROM account;

更新數據
UPDATE 語句用於更新表中的記錄。

UPDATE user
SET username='robot', password='robot'
WHERE username = 'root';

刪除數據
DELETE 語句用於刪除表中的記錄。

TRUNCATE TABLE 可以清空表,也就是刪除所有行。

刪除表中的指定數據

DELETE FROM user
WHERE username = 'robot';

清空表中的數據

TRUNCATE TABLE user;
查詢數據
SELECT 語句用於從數據庫中查詢數據。

DISTINCT 用於返回唯一不同的值。它作用於所有列,也就是說所有列的值都相同纔算相同。

LIMIT 限制返回的行數。可以有兩個參數,第一個參數爲起始行,從 0 開始;第二個參數爲返回的總行數。

ASC :升序(默認)
DESC :降序

查詢單列

SELECT prod_name
FROM products;

查詢多列

SELECT prod_id, prod_name, prod_price
FROM products;

查詢所有列

ELECT *
FROM products;

查詢不同的值

SELECT DISTINCT
vend_id FROM products;

限制查詢結果

-- 返回前 5 行
SELECT * FROM mytable LIMIT 5;
SELECT * FROM mytable LIMIT 0, 5;
-- 返回第 3 ~ 5 行
SELECT * FROM mytable LIMIT 2, 3;

三、子查詢
子查詢是嵌套在較大查詢中的 SQL 查詢。子查詢也稱爲內部查詢或內部選擇,而包含子查詢的語句也稱爲外部查詢或外部選擇。

  • 子查詢可以嵌套在 SELECT,INSERT,UPDATE 或 DELETE 語句內或另一個子查詢中。
  • 子查詢通常會在另一個 SELECT 語句的 WHERE 子句中添加。
  • 您可以使用比較運算符,如 >,<,或 =。比較運算符也可以是多行運算符,如 IN,ANY 或 ALL。
  • 子查詢必須被圓括號 () 括起來。
  • 內部查詢首先在其父查詢之前執行,以便可以將內部查詢的結果傳遞給外部查詢。執行過程可以參考下圖:

子查詢的子查詢

SELECT cust_name, cust_contact
FROM customers
WHERE cust_id IN (SELECT cust_id
                  FROM orders
                  WHERE order_num IN (SELECT order_num
                                      FROM orderitems
                                      WHERE prod_id = 'RGAN01'));

WHERE

  • WHERE 子句用於過濾記錄,即縮小訪問數據的範圍。
  • WHERE 後跟一個返回 true 或 false 的條件。
  • WHERE 可以與 SELECT,UPDATE 和 DELETE 一起使用。

可以在 WHERE 子句中使用的操作符

SELECT 語句中的 WHERE 子句

SELECT * FROM Customers
WHERE cust_name = 'Kids Place';

UPDATE 語句中的 WHERE 子句

UPDATE Customers
SET cust_name = 'Jack Jones'
WHERE cust_name = 'Kids Place';

DELETE 語句中的 WHERE 子句

DELETE FROM Customers
WHERE cust_name = 'Kids Place';

IN 和 BETWEEN

  • IN 操作符在 WHERE 子句中使用,作用是在指定的幾個特定值中任選一個值。
  • BETWEEN 操作符在 WHERE 子句中使用,作用是選取介於某個範圍內的值。

IN 示例

SELECT *
FROM products
WHERE vend_id IN ('DLL01', 'BRS01');

BETWEEN 示例

SELECT *
FROM products
WHERE prod_price BETWEEN 3 AND 5;

AND、OR、NOT

  • AND、OR、NOT 是用於對過濾條件的邏輯處理指令。
  • AND 優先級高於 OR,爲了明確處理順序,可以使用 ()。
  • AND 操作符表示左右條件都要滿足。
  • OR 操作符表示左右條件滿足任意一個即可。
  • NOT 操作符用於否定一個條件。

AND 示例

SELECT prod_id, prod_name, prod_price
FROM products
WHERE vend_id = 'DLL01' AND prod_price <= 4;

OR 示例

SELECT prod_id, prod_name, prod_price
FROM products
WHERE vend_id = 'DLL01' OR vend_id = 'BRS01';

NOT 示例

SELECT *
FROM products
WHERE prod_price NOT BETWEEN 3 AND 5;

LIKE

  • LIKE 操作符在 WHERE 子句中使用,作用是確定字符串是否匹配模式。
  • 只有字段是文本值時才使用 LIKE。
  • LIKE 支持兩個通配符匹配選項:% 和 _。
  • 不要濫用通配符,通配符位於開頭處匹配會非常慢。
  • % 表示任何字符出現任意次數。
  • _ 表示任何字符出現一次。

% 示例

SELECT prod_id, prod_name, prod_price
FROM products
WHERE prod_name LIKE '%bean bag%';

_ 示例

SELECT prod_id, prod_name, prod_price
FROM products
WHERE prod_name LIKE '__ inch teddy bear';

四、連接和組合
連接(JOIN)
如果一個 JOIN 至少有一個公共字段並且它們之間存在關係,則該 JOIN 可以在兩個或多個表上工作。

連接用於連接多個表,使用 JOIN 關鍵字,並且條件語句使用 ON 而不是 WHERE。

JOIN 保持基表(結構和數據)不變。

JOIN 有兩種連接類型:內連接和外連接。

內連接又稱等值連接,使用 INNER JOIN 關鍵字。在沒有條件語句的情況下返回笛卡爾積。

自連接可以看成內連接的一種,只是連接的表示自身而已。

自然連接是把同名列通過 = 測試連接起來的,同名列可以有多個。

內連接 vs 自然連接

內連接提供連接的列,而自然連接自動連接所有同名列。
外連接返回一個表中的所有行,並且僅返回來自次表中滿足連接條件的那些行,即兩個表中的列是相等的。外連接分爲左外連接、右外連接、全外連接(Mysql 不支持)。
左外連接就是保留左表沒有關聯的行。
右外連接就是保留右表沒有關聯的行。

連接 vs 子查詢

連接可以替換子查詢,並且比子查詢的效率一般會更快。

內連接(INNER JOIN)

SELECT vend_name, prod_name, prod_price
FROM vendors INNER JOIN products
ON vendors.vend_id = products.vend_id;

自連接

SELECT c1.cust_id, c1.cust_name, c1.cust_contact
FROM customers c1, customers c2
WHERE c1.cust_name = c2.cust_name
AND c2.cust_contact = 'Jim Jones';

自然連接(NATURAL JOIN)

SELECT *
FROM Products
NATURAL JOIN Customers;

左連接(LEFT JOIN)

SELECT customers.cust_id, orders.order_num
FROM customers LEFT JOIN orders
ON customers.cust_id = orders.cust_id;

右連接(RIGHT JOIN)

SELECT customers.cust_id, orders.order_num
FROM customers RIGHT JOIN orders
ON customers.cust_id = orders.cust_id;

組合(UNION)
UNION 運算符將兩個或更多查詢的結果組合起來,並生成一個結果集,其中包含來自 UNION 中參與查詢的提取行。

UNION 基本規則

  • 所有查詢的列數和列順序必須相同。
  • 每個查詢中涉及表的列的數據類型必須相同或兼容。
  • 通常返回的列名取自第一個查詢。
  • 默認會去除相同行,如果需要保留相同行,使用 UNION ALL。
  • 只能包含一個 ORDER BY 子句,並且必須位於語句的最後。

應用場景

  • 在一個查詢中從不同的表返回結構數據。
  • 對一個表執行多個查詢,按一個查詢返回數據。

組合查詢

SELECT cust_name, cust_contact, cust_email
FROM customers
WHERE cust_state IN ('IL', 'IN', 'MI')
UNION
SELECT cust_name, cust_contact, cust_email
FROM customers
WHERE cust_name = 'Fun4All';

JOIN vs UNION

  • JOIN 中連接表的列可能不同,但在 UNION 中,所有查詢的列數和列順序必須相同。
  • UNION 將查詢之後的行放在一起(垂直放置),但 JOIN 將查詢之後的列放在一起(水平放置),即它構成一個笛卡爾積。

五、函數
注意:不同數據庫的函數往往各不相同,因此不可移植。本節主要以 Mysql 的函數爲例。

文本處理

其中, SOUNDEX() 可以將一個字符串轉換爲描述其語音表示的字母數字模式。

SELECT *
FROM mytable
WHERE SOUNDEX(col1) = SOUNDEX('apple')

日期和時間處理
日期格式:YYYY-MM-DD

時間格式:HH:MM:SS

mysql> SELECT NOW();
2018-4-14 20:25:11

數值處理

AVG() 會忽略 NULL 行。

使用 DISTINCT 可以讓彙總函數值彙總不同的值。

SELECT AVG(DISTINCT col1) AS avg_col
FROM mytable

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章