一 、排序檢索數據:讓結果更具邏輯性

默認情況下,SQL檢索數據的順序依賴於數據在表中的物理存儲順序(如插入順序),這種順序毫無規律且不穩定。ORDER BY子句的核心作用的是對檢索結果進行明確排序,使數據呈現更具邏輯性,方便後續分析與使用。

1.1 基礎排序:ORDER BY子句的核心用法

ORDER BY是實現排序的核心關鍵字,其基本語法為:

SELECT 列名1, 列名2... FROM 表名 ORDER BY 排序列1, 排序列2...;
  • 核心規則ORDER BY必須是SELECT語句的最後一條子句,位於WHERE(若有)之後。
  • 默認行為:未指定排序方向時,默認按升序(ASC) 排列(從A到Z、從0到9)。
  • 基礎示例:從Products表中檢索產品名稱,並按產品名稱升序排序:
SELECT prod_name FROM Products ORDER BY prod_name;

1.2 多列排序:按優先級定義順序

當需要按多個維度排序時,可在ORDER BY後指定多個列名,列名之間用逗號分隔,排序優先級遵循“先第一列,後第二列”的規則。

  • 語法示例:從Products表中檢索產品ID、價格和名稱,先按價格升序,再按名稱升序排序:
SELECT prod_id, prod_price, prod_name FROM Products ORDER BY prod_price, prod_name;
  • 關鍵説明:僅當第一列存在重複值時,第二列的排序才會生效。例如,若所有產品價格唯一,那麼產品名稱的排序將無實際意義。

1.3 按列位置排序:簡化語法的靈活選擇

除了指定列名,ORDER BY還支持按列在SELECT語句中的位置排序(列位置從1開始計數)。

  • 語法示例:與上述多列排序功能一致,用列位置替代列名:
SELECT prod_id, prod_price, prod_name FROM Products ORDER BY 2, 3;
  • 其中“2”對應prod_price,“3”對應prod_name
  • 優點:簡化SQL語句,避免重複輸入長列名。
  • 缺點
  1. 可讀性差,他人難以快速理解排序依據;
  2. 若修改SELECT語句中列的順序,ORDER BY的排序邏輯會同步改變,易引發錯誤;
  3. 無法對未在SELECT中列出的列進行排序。

1.4 指定排序方向:升序與降序的靈活切換

使用DESC關鍵字可實現降序排序(從Z到A、從9到0),ASC(升序)可省略(默認行為)。

  • 單列降序示例:檢索產品信息,按價格降序排序(最貴的產品在前):
SELECT prod_id, prod_price, prod_name FROM Products ORDER BY prod_price DESC;
  • 多列混合排序示例:先按價格降序,再按名稱升序:
SELECT prod_id, prod_price, prod_name FROM Products ORDER BY prod_price DESC, prod_name;
  • 關鍵注意DESC僅作用於其直接緊跟的列。若需對多個列都進行降序排序,必須為每個列單獨指定DESC,例如:
-- 錯誤:僅prod_price降序,prod_name仍為升序
SELECT prod_id, prod_price, prod_name FROM Products ORDER BY prod_price, prod_name DESC;
-- 正確:兩列均降序
SELECT prod_id, prod_price, prod_name FROM Products ORDER BY prod_price DESC, prod_name DESC;

1.5 排序的特殊注意事項

  • 區分大小寫:文本排序的大小寫規則依賴於DBMS及其配置。多數DBMS默認“不區分大小寫”(A與a視為相同),但部分系統可配置為區分大小寫,此時'Apple''apple'會被視為不同值。
  • 非選擇列排序ORDER BY支持對未在SELECT中列出的列排序(例如:檢索產品名稱,但按價格排序),這是合法且常用的操作。

二、 過濾數據:精準獲取目標數據

數據庫表通常包含大量數據,WHERE子句的核心作用是指定過濾條件,僅檢索滿足條件的行,避免返回無關數據,提升查詢效率並減少網絡傳輸開銷。

2.1 WHERE子句的基礎用法

WHERE子句用於過濾行數據,其基本語法為:

SELECT 列名1, 列名2... FROM 表名 WHERE 過濾條件;
  • 核心規則WHERE子句位於FROM子句之後、ORDER BY子句之前(若有)。
  • 基礎示例:從Products表中檢索價格為3.49美元的產品名稱和價格:
SELECT prod_name, prod_price FROM Products WHERE prod_price = 3.49;
  • SQL過濾vs應用過濾:優先使用WHERE在數據庫端過濾數據,而非在應用程序中過濾。數據庫端過濾更高效,且能減少網絡傳輸的數據量;應用端過濾會浪費服務器資源和帶寬。

2.2 常用過濾操作符:覆蓋多數業務場景

SQL提供多種操作符用於構建過濾條件,以下是書中重點介紹的核心操作符及用法:

2.2.1 等於(=)與不等於(<>/!=)

  • 等於(=):匹配列值與指定值完全相等的行(注意:字符串需用單引號括起,數值無需引號)。
    示例:檢索供應商ID為DLL01的產品:
SELECT prod_name, vend_id FROM Products WHERE vend_id = 'DLL01';
  • 不等於(<>/!=):匹配列值與指定值不相等的行(<> 是ANSI標準,!=為部分DBMS擴展,如MySQL,Microsoft Access僅支持<> )。
    示例:檢索供應商ID不是DLL01的產品:
SELECT prod_name, vend_id FROM Products WHERE vend_id <> 'DLL01';

2.2.2 範圍匹配:BETWEEN操作符

BETWEEN用於匹配指定範圍內的所有值,包含範圍的起始值和結束值,語法為BETWEEN 起始值 AND 結束值

  • 示例:檢索價格在5美元到10美元之間的產品:
SELECT prod_name, prod_price FROM Products WHERE prod_price BETWEEN 5 AND 10;
  • 該語句等價於prod_price >= 5 AND prod_price <= 10

2.2.3 空值匹配:IS NULL操作符

NULL表示“無值”(區別於0、空字符串''),判斷列值是否為NULL需使用IS NULL(不能用= NULL,SQL中NULL與任何值比較結果均為NULL)。

  • 示例:檢索沒有電子郵件地址(cust_emailNULL)的顧客名稱:
SELECT cust_name FROM Customers WHERE cust_email IS NULL;
  • 注意:IS NOT NULL用於匹配非空值,示例:檢索有電子郵件地址的顧客:
SELECT cust_name FROM Customers WHERE cust_email IS NOT NULL;

2.2.4 其他常用操作符

操作符

説明

示例

>

大於

WHERE prod_price > 10(價格大於10美元)

<

小於

WHERE prod_price < 5(價格小於5美元)

>=

大於等於

WHERE prod_price >= 8(價格大於等於8美元)

<=

小於等於

WHERE prod_price <= 3(價格小於等於3美元)

!>

不大於(等價於<=

WHERE prod_price !> 5(價格不大於5美元)

!<

不小於(等價於>=

WHERE prod_price !< 10(價格不小於10美元)

2.3 過濾條件的關鍵注意事項

  • 字符串與數值的引號規則:字符串類型的列(如vend_idprod_name)匹配時,值必須用單引號括起;數值類型的列(如prod_pricequantity)匹配時,無需加引號。
  • NULL的特殊性:包含NULL的行不會出現在普通過濾條件中(如WHERE prod_price <> 3.49不會返回prod_priceNULL的行),需單獨用IS NULL/IS NOT NULL處理。
  • 操作符兼容性:部分操作符並非所有DBMS都支持(如!>!<),優先使用<=>=等ANSI標準操作符,確保代碼可移植性。

三、排序語法速查(ORDER BY)

1. 核心功能

SELECT檢索結果按指定規則排序,解決默認物理存儲順序無規律的問題。

2. 基礎語法

功能類型

語法格式

關鍵説明

單列排序

SELECT 列1, 列2... FROM 表名 ORDER BY 排序列 [ASC/DESC];

- ASC:升序(默認,可省略,如A→Z、0→9)

- DESC:降序(如Z→A、9→0)

- ORDER BY必須是SELECT最後一條子句

多列排序

SELECT 列1, 列2... FROM 表名 ORDER BY 排序列1 [ASC/DESC], 排序列2 [ASC/DESC];

按列1優先級排序,僅當列1有重複值時,列2排序才生效

按列位置排序

SELECT 列1, 列2, 列3... FROM 表名 ORDER BY 列位置1, 列位置2;

列位置從1開始計數(如“2”對應SELECT中第2列),不推薦(可讀性差、易出錯)

3. 關鍵示例(基於Products表)

需求描述

SQL語句

按產品名稱升序排序

SELECT prod_name FROM Products ORDER BY prod_name;

按價格降序、名稱升序排序

SELECT prod_id, prod_price, prod_name FROM Products ORDER BY prod_price DESC, prod_name;

按列位置(第2列)排序

SELECT prod_id, prod_price, prod_name FROM Products ORDER BY 2;

4. 注意事項

  1. DESC作用範圍:僅對緊跟的列生效,多列降序需為每列單獨加DESC(如ORDER BY price DESC, name DESC)。
  2. 非選擇列排序:支持對未在SELECT中列出的列排序(如SELECT prod_name FROM Products ORDER BY prod_price;)。
  3. 大小寫敏感性:文本排序是否區分大小寫(如“A”與“a”),依賴DBMS配置(多數默認不區分)。

四、過濾語法速查(WHERE)

1. 核心功能

通過指定條件篩選表中行數據,僅返回滿足條件的結果,減少無關數據傳輸與處理開銷。

2. 基礎語法

功能類型

語法格式

關鍵説明

WHERE基礎用法

SELECT 列1, 列2... FROM 表名 WHERE 過濾條件;

- WHERE位於FROM之後、ORDER BY之前

- 過濾條件由“列名+操作符+值”組成

多條件組合

(見“高級過濾”,需結合AND/OR,詳見第5課)

暫不涉及,核心關注單條件過濾

3. 常用操作符與示例(基於Products/Customers表)

操作符

功能描述

語法格式

關鍵示例

注意事項

=

等於

列名 = 值

檢索價格=3.49的產品:

SELECT prod_name, prod_price FROM Products WHERE prod_price = 3.49;

數值無需引號,字符串需加單引號(如vend_id = 'DLL01'

<>/`!=

不等於

列名 <> 值/列名 != 值

檢索供應商≠DLL01的產品:

SELECT prod_name, vend_id FROM Products WHERE vend_id <> 'DLL01';

<>是ANSI標準,!=非通用(如Access僅支持<>

BETWEEN

範圍匹配(含邊界)

列名 BETWEEN 起始值 AND 結束值

檢索價格5~10的產品:

SELECT prod_name, prod_price FROM Products WHERE prod_price BETWEEN 5 AND 10;

等價於>= 起始值 AND <= 結束值,邊界值必含

IS NULL

匹配空值(無值)

列名 IS NULL

檢索無郵箱的顧客:

SELECT cust_name FROM Customers WHERE cust_email IS NULL;

不能用= NULLNULL與任何值比較均為NULL

IS NOT NULL

匹配非空值

列名 IS NOT NULL

檢索有郵箱的顧客:

SELECT cust_name FROM Customers WHERE cust_email IS NOT NULL;

-

>/<

大於/小於

列名 > 值/列名 < 值

檢索價格>10的產品:

SELECT prod_name, prod_price FROM Products WHERE prod_price > 10;

-

>=/<=

大於等於/小於等於

列名 >= 值/列名 <= 值

檢索價格<=5的產品:

SELECT prod_name, prod_price FROM Products WHERE prod_price <= 5;

-

4. 注意事項

  1. 引號規則:字符串值必須用單引號括起(如'DLL01'),數值/日期值無需引號(如3.492024-01-01)。
  2. NULL特殊性:含NULL的行不會出現在普通過濾中(如WHERE prod_price <> 3.49不會返回prod_priceNULL的行)。
  3. 數據類型匹配:過濾條件的值需與列數據類型一致(如數值列不能用字符串過濾,如prod_price = 'abc'會報錯)。

五、常見錯誤規避

錯誤類型

錯誤示例

正確示例

原因分析

ORDER BY位置錯誤

SELECT prod_name FROM Products ORDER BY prod_name WHERE prod_price > 5;

SELECT prod_name FROM Products WHERE prod_price > 5 ORDER BY prod_name;

ORDER BY必須在WHERE之後

DESC作用範圍錯誤

SELECT prod_price, prod_name FROM Products ORDER BY prod_price, prod_name DESC;

SELECT prod_price, prod_name FROM Products ORDER BY prod_price DESC, prod_name DESC;

DESC僅作用於緊跟的列,多列降序需逐個加

字符串未加引號

SELECT prod_name FROM Products WHERE vend_id = DLL01;

SELECT prod_name FROM Products WHERE vend_id = 'DLL01';

字符串值必須加單引號

NULL判斷用= NULL

SELECT cust_name FROM Customers WHERE cust_email = NULL;

SELECT cust_name FROM Customers WHERE cust_email IS NULL;

NULL不能用=判斷,需用IS NULL

按列位置排序易出錯

SELECT prod_price, prod_name FROM Products ORDER BY 1, 2;(後續修改列順序)

SELECT prod_price, prod_name FROM Products ORDER BY prod_price, prod_name;

列位置依賴SELECT列順序,修改後邏輯易變

六、核心原則

  1. 排序優先用列名:避免按列位置排序,提升代碼可讀性與可維護性。
  2. 過濾優先數據庫端:用WHERE在數據庫篩選數據,而非在應用端過濾(減少帶寬與資源消耗)。
  3. 複雜查詢分步測試:先驗證WHERE過濾邏輯,再添加ORDER BY排序,降低調試難度。