本文 AI 產出,尚未審核

MySQL SELECT 基本語法

簡介

在資料庫的日常操作中,SELECT 是最常使用、也是最重要的語句之一。它負責從資料表中取出符合條件的資料,讓我們能夠進一步分析、呈現或處理。無論是建立報表、實作搜尋功能,或是後端 API 回傳資料,都離不開 SELECT。
本單元將從最基礎的語法說起,帶你一步步掌握查詢的核心概念,並提供實務範例、常見陷阱與最佳實踐,讓你能在開發過程中快速、正確地取出想要的資料。

核心概念

1. 基本 SELECT 結構

最簡單的 SELECT 只需要指定要查詢的欄位與來源表格:

SELECT column1, column2
FROM table_name;
  • SELECT 後面列出欲返回的欄位,若要全部欄位可使用 *
  • FROM 指定資料來源的資料表。

小技巧:在開發階段,先寫 SELECT * 確認欄位名稱,再逐步改為具體欄位,能減少拼寫錯誤。

2. 為什麼要使用別名 (Alias)

別名讓回傳的欄位名稱更易讀,或在多表查詢時避免衝突。

SELECT employee_id AS id,
       first_name AS 名,
       salary AS 月薪
FROM employees;
  • AS 為可選的關鍵字,直接寫空格也可:employee_id id
  • 別名支援 Unicode,因此可以直接使用中文欄位名。

3. 條件篩選 – WHERE

WHERE 讓我們只取出符合條件的資料,常見的比較運算子有 =、<>、>、<、BETWEEN、LIKE 等。

SELECT *
FROM orders
WHERE order_date >= '2024-01-01'
  AND status = 'completed';
  • 多條件使用 AND(同時滿足)或 OR(任一滿足)。
  • 日期字串建議使用 ISO 標準 YYYY-MM-DD,可避免時區與格式問題。

4. 排序 – ORDER BY

ORDER BY 讓結果依指定欄位排序,預設為 升冪 (ASC),欲降冪則使用 DESC

SELECT product_name, price
FROM products
WHERE price > 1000
ORDER BY price DESC;
  • 多欄位排序時,依左至右的優先順序依序比較:ORDER BY category ASC, price DESC

5. 限制筆數 – LIMIT (MySQL 專屬)

在大量資料時,常用 LIMIT 只取前幾筆,配合 OFFSET 可實作分頁。

-- 取第 2 頁,每頁 10 筆
SELECT *
FROM customers
ORDER BY created_at DESC
LIMIT 10 OFFSET 10;

提醒OFFSET 效能較差,若資料筆數龐大,建議改用「鍵值分頁」或「游標」技巧。

程式碼範例

範例 1:簡單查詢所有欄位

-- 取得 employees 表的全部資料
SELECT * 
FROM employees;

此查詢在開發測試階段很有用,但正式上線時建議改為指定欄位,以減少不必要的 I/O。

範例 2:欄位別名與條件篩選

SELECT employee_id      AS 員工編號,
       CONCAT(first_name, ' ', last_name) AS 姓名,
       salary            AS 月薪
FROM employees
WHERE salary BETWEEN 30000 AND 60000   -- 薪資介於 3~6 萬
  AND status = 'active';               -- 僅列出在職員工

CONCAT 用來合併字串,讓姓名一次呈現在同一欄位。

範例 3:排序與分頁

SELECT order_id, customer_id, total_amount, order_date
FROM orders
WHERE order_date >= '2024-01-01'
ORDER BY order_date DESC, total_amount ASC
LIMIT 20 OFFSET 40;   -- 取第 3 頁 (每頁 20 筆)

結合 ORDER BYLIMIT,即可快速完成分頁功能。

範例 4:使用聚合函式與 GROUP BY

SELECT customer_id,
       COUNT(*)            AS 訂單筆數,
       SUM(total_amount)   AS 總消費金額
FROM orders
WHERE order_date BETWEEN '2024-01-01' AND '2024-12-31'
GROUP BY customer_id
HAVING SUM(total_amount) > 5000;   -- 只保留消費超過 5,000 的客戶

GROUP BY 必須與聚合函式(COUNTSUMAVG…)一起使用,HAVING 用於篩選聚合結果。

範例 5:子查詢 (Nested SELECT)

SELECT e.employee_id,
       e.first_name,
       e.last_name,
       (SELECT COUNT(*)
        FROM orders o
        WHERE o.employee_id = e.employee_id) AS 訂單數量
FROM employees e
WHERE e.status = 'active';

子查詢在 SELECT 中直接計算每位員工的訂單筆數,避免額外的 JOIN。

常見陷阱與最佳實踐

陷阱 說明 解決方式
使用 SELECT * 會把所有欄位都拉回,增加 I/O 與網路流量。 僅列出需要的欄位,並使用別名提升可讀性。
忘記加上 WHERE 大表全表掃描可能導致瞬間鎖表、效能崩潰。 務必檢查條件,必要時加上索引。
LIKE 前綴 % %abc 會讓搜尋無法使用索引,變成全表掃描。 若可能,盡量改成 abc%,或使用全文索引 (FULLTEXT)。
忽略 NULL 判斷 = 無法比較 NULL,會得到意外結果。 使用 IS NULL / IS NOT NULLCOALESCE
LIMITOFFSET 大數值 大量偏移會造成 MySQL 讀取大量不必要的行。 採用「鍵值分頁」 (WHERE id > last_id) 或使用 Cursor
未使用交易 (TRANSACTION) 多筆 SELECT/UPDATE 組合時,資料可能不一致。 需要時以 START TRANSACTION 包裹,確保原子性。

最佳實踐小結

  1. 明確指定欄位,配合別名提升可讀性。
  2. 適時加索引WHEREJOINORDER BYGROUP BY 常用欄位皆應考慮建立索引。
  3. 避免過度使用子查詢:在可能的情況下,改用 JOIN 以提升效能。
  4. 使用參數化查詢(Prepared Statement)防止 SQL Injection。
  5. 盡量在開發環境先測試,觀察 EXPLAIN 執行計畫,找出瓶頸。

實際應用場景

場景 SELECT 用法 為何重要
商品搜尋 SELECT id, name, price FROM products WHERE name LIKE '手機%' ORDER BY price ASC LIMIT 20; 為前端即時搜尋提供快速、分頁結果,提升使用者體驗。
月度營收報表 SELECT DATE_FORMAT(order_date,'%Y-%m') AS month, SUM(total_amount) AS revenue FROM orders GROUP BY month ORDER BY month; 直接在資料庫完成彙總,減少程式端計算,報表產出更即時。
使用者登入檢查 SELECT user_id FROM users WHERE email = ? AND password_hash = ? AND status = 'active'; 只回傳必要的欄位,降低資料外洩風險,同時配合參數化查詢提升安全性。
後端 API 分頁 SELECT * FROM articles ORDER BY created_at DESC LIMIT 10 OFFSET 30; 讓 API 能依頁面返回固定筆數,減少前端一次載入過多資料。
資料遷移 INSERT INTO archive_orders SELECT * FROM orders WHERE order_date < '2023-01-01'; 使用 SELECT 搭配 INSERT,一次性搬移大量舊資料,簡化 ETL 流程。

總結

SELECT 是 MySQL 與所有關聯式資料庫的核心查詢語句,掌握它的基本語法與常用技巧,是每位開發者的必備能力。本文從 基本結構條件篩選排序與分頁聚合與子查詢 四大面向說明,並提供多個實務範例、常見陷阱與最佳實踐,協助你在日常開發中寫出 高效、可讀、且安全 的查詢。未來只要持續運用 EXPLAIN 觀察執行計畫、適時調整索引與查詢寫法,你就能在面對大資料量時,仍保持查詢的快速回應,為系統穩定性與使用者體驗奠定堅實基礎。祝你在 MySQL 的世界裡查詢無礙,開發順利!