緣起
從"燕十八"接觸到 "MySQL 查詢模型",對 SQL 語句的理解有醍醐灌頂之感.
贈人玫瑰, 手有餘香, 分享自己對這一模型的理解.
先說結論
把資料庫表的"列"看成"變數",把" SQL 查詢語句"理解成程式語言中的"流程控制語句".
4 個要點:
- 把"列"看成"變數", "變數"是可以計算的;
-
WHERE
是"布林表示式/判斷條件", 它的值為"true/false"; -
FROM
是指定"迴圈遍歷"的範圍 - 當
WHERE
為true時, 就將這一行的資料提取出來;
查詢模型
比如對於下面的資料:
id | name | age |
---|---|---|
1 | ober | 89 |
2 | lucy | 17 |
3 | lilei | 19 |
SQL 查詢語句 SELECT name, age FROM user WHERE id = 2
可以理解成"程式設計中的迴圈判斷控制語句":
- 把"列" (id/name/age) 看成"變數", 程式會迴圈歷遍每行資料;
-
WHERE
是表示式,id = 2
是判斷條件(布林表示式), 它的值為"true/false"; - 如果判斷
id = 2
為true時, 就執行SELECT name, age
,把變數name和age取出來; - 如果判斷
id = 2
為false, 則完成這次判斷, 讀取下一行, 更新變數為下一行的值, 繼續判斷; - 所以這句 SQL 語句可以理解成**"在 user 中遍歷檢索, 當
WHRER uid = 2
為真時, 執行SELECT name, age
:
for (i = 0; i < count(*), i++){
if (uid = 2){
SELECT name, age;
}
}
複製程式碼
延伸
理解"計算欄位"
既然將"列"理解成"變數",而"變數"是可以計算的, 就很容易理解"計算欄位"的概念:
- "拼接欄位"就是字串運算子, 或者說格式化輸出
- 算數計算:
SELECT name, age+1 FROM user WHERE uid=2 /* 輸出時age+1 */
複製程式碼
理解"別名"
"別名",也是"變數", 比如
SELECT AVG(prod_price) AS avg_price
FROM Products;
複製程式碼
表示檢索出Products表中所有產品的平均價格, 該平均價格賦給別名avg_price
(類似於變數)
理解"OFFSET"
資料庫表的資料類似用"陣列"形式組織, 就像mysqli_fetch_assoc
提取的陣列, 陣列的索引位置就是從0開始算起. 如果SELECT查詢時新增OFFSET 1
條件,將會檢索第2行, 而不是第1行, 因為第1個被檢索的行是第0行, 而不是第1行;
理解 where 1
提問:
SQL 查詢語句 SELECT * FROM user WHERE 1
將會如何執行?
解答:
因為 WHERE 是表示式/判斷條件, 而 1
表示 true
, 所以判斷條件永遠為 true
,因此前面的 SQL 語句會遍歷檢索出所有的資料.
如果換成 SELECT * FROM user WHERE 0
或者 SELECT * FROM user WHERE false
, 就不執行 SELECT
, 不返回資料.
PS. 不光是 1 表示 true, "2, 3, 4..."也可以.