優先序越高越先運算。同一行者優先序相同,依左結合性(左至右)計算。
| 優先序 | 運算子 | 類型 | 說明 |
|---|---|---|---|
| 1 (最低) | := | 指派 | 變數指派(如 SELECT @a := 1) |
| 2 | ||, OR, XOR | 邏輯或 | 邏輯 OR、XOR |
| 3 | &&, AND | 邏輯與 | 邏輯 AND |
| 4 | NOT | 邏輯非 | 邏輯 NOT(受 HIGH_NOT_PRECEDENCE 影響) |
| 5 | BETWEEN, CASE, WHEN, THEN, ELSE | 流程控制 | 範圍判斷、CASE 運算式 |
| 6 | =, <=>, >=, >, <=, <, <>, !=, IS, LIKE, REGEXP, IN | 比較 | 比較運算子、NULL 安全比較 <=> |
| 7 | | | 位元或 | Bitwise OR |
| 8 | & | 位元與 | Bitwise AND |
| 9 | <<, >> | 位元位移 | 左移、右移 |
| 10 | -, + | 加減 | 減法、加法 |
| 11 | *, /, DIV, %, MOD | 乘除 | 乘法、除法、整數除法、取餘 |
| 12 | ^ | 位元異或 | Bitwise XOR |
| 13 | - (一元), ~ (一元) | 一元運算 | 負號、位元取反 |
| 14 | ! | 邏輯非 | 非標準 NOT(優先序高於標準 NOT) |
| 15 (最高) | BINARY, COLLATE | 型別轉換 | 二進位字串轉換、排序規則指定 |
啟用 HIGH_NOT_PRECEDENCE SQL 模式時,NOT 優先序等同 !(第 14 級),否則為第 4 級。
-- 未啟用 HIGH_NOT_PRECEDENCE(預設)
SELECT NOT 1 = 0; -- 解析為 NOT (1 = 0) → NOT 0 → 1
-- 啟用後
SET sql_mode = 'HIGH_NOT_PRECEDENCE';
SELECT NOT 1 = 0; -- 解析為 (NOT 1) = 0 → 0 = 0 → 1
SELECT 1 + 2 * 3; -- 7 (先乘後加)
SELECT (1 + 2) * 3; -- 9 (括號優先)
SELECT 10 - 5 - 2; -- 3 (左結合: (10-5)-2)
SELECT 10 - (5 - 2); -- 7 (括號改變順序)
-- 解析為 (a = b) = c,通常非預期
SELECT 1 = 1 = 1; -- (1=1)=1 → 1=1 → 1
-- 正確寫法
SELECT 1 = 1 AND 1 = 1; -- 1
-- 預期:a=1 且 b=2
SELECT * FROM t WHERE a = 1 AND b = 2; -- 正確
-- 危險:|| 優先序低於 =
SELECT * FROM t WHERE a = 1 || b = 2; -- 解析為 a = (1 || b) = 2 錯誤!
-- 應寫成
SELECT * FROM t WHERE a = 1 OR b = 2;
SELECT @a := 1, @b := @a + 1; -- @a=1, @b=2
-- 注意::= 優先序最低,整個運算式最後才指派
SELECT -2 ^ 2; -- (-2) ^ 2 = 4 (一元負號優先序 13 > ^ 的 12)
SELECT - (2 ^ 2); -- -4 (括號改變)
-- 快速驗證優先序
SELECT
1 + 2 * 3 AS '加乘',
(1 + 2) * 3 AS '括號優先',
10 - 5 - 2 AS '左結合減法',
10 - (5 - 2) AS '括號改變',
NOT 0 = 1 AS 'NOT比較',
1 = 1 = 1 AS '比較鏈結',
-2 ^ 2 AS '負號冪次';
|| 與 OR、&& 與 AND 擇一使用AND 連接多個比較SELECT @@sql_mode 確認 HIGH_NOT_PRECEDENCE 狀態熟悉運算子優先序能避免微妙邏輯錯誤,但「明確括號」永遠是最好的文件與保護!