返回首頁SQL

SQL 語法大全:SELECT、JOIN、WHERE 完整查詢指令教學【2025】

22 min 分鐘閱讀
#SQL語法#SELECT#WHERE#JOIN#GROUP BY#SQL教學#資料庫查詢#SQL指令#資料篩選#聚合函數

SQL 語法大全:SELECT、JOIN、WHERE 完整查詢指令教學【2025】

引言:掌握 SQL 語法的重要性

你有沒有想過,為什麼資料分析師的履歷上幾乎都寫著「熟悉 SQL」?

答案很簡單:SQL 是與資料庫溝通的共通語言。無論你使用 MySQL、PostgreSQL 還是 SQL Server,核心語法都是相通的。

這篇文章將系統性地介紹 SQL 查詢語法的每一個環節。從最基本的 SELECT 開始,到 WHERE 條件篩選、JOIN 多表連接,再到 GROUP BY 分組統計。讀完這篇,你就能寫出涵蓋 90% 日常需求的 SQL 查詢。

如果你是完全的新手,建議先閱讀 SQL 完整指南:從入門到精通 了解基本概念。

插圖 1:開發者在 IDE 中撰寫 SQL 查詢

SQL 查詢語法概觀

SQL 語句的基本結構

一個完整的 SQL 查詢語句通常包含以下子句:

SELECT 欄位           -- 1. 選取要顯示的欄位
FROM 資料表           -- 2. 指定資料來源
WHERE 條件            -- 3. 篩選資料(可選)
GROUP BY 分組欄位     -- 4. 分組統計(可選)
HAVING 分組條件       -- 5. 篩選分組結果(可選)
ORDER BY 排序欄位     -- 6. 排序結果(可選)
LIMIT 筆數            -- 7. 限制回傳筆數(可選)

SQL 執行順序

這是很多人搞混的地方:SQL 的撰寫順序執行順序不同。

執行順序(重要!):

  1. FROM → 決定資料來源
  2. WHERE → 篩選個別資料列
  3. GROUP BY → 進行分組
  4. HAVING → 篩選分組結果
  5. SELECT → 選取要顯示的欄位
  6. ORDER BY → 排序
  7. LIMIT → 限制筆數

理解執行順序能幫助你避免很多錯誤。例如,你不能在 WHERE 中使用 SELECT 定義的別名,因為 WHERE 比 SELECT 先執行。

SQL 語法分類

SQL 語法依功能分為四大類:

類別全名常用指令用途
DQLData Query LanguageSELECT查詢資料
DMLData Manipulation LanguageINSERT、UPDATE、DELETE操作資料
DDLData Definition LanguageCREATE、ALTER、DROP定義結構
DCLData Control LanguageGRANT、REVOKE權限控制

本文主要聚焦在 DQL(查詢語言),這也是日常使用最頻繁的部分。

想了解 DML 操作,請參考 SQL CRUD 操作完整指南


SELECT 查詢語法完整解析

基本 SELECT 結構

SELECT 是 SQL 最核心的指令,用來從資料表中擷取資料。

最簡單的查詢:

-- 查詢所有欄位
SELECT * FROM employees;

-- 查詢特定欄位
SELECT name, department, salary FROM employees;

重要提醒:在正式環境中避免使用 SELECT *,原因有三:

  1. 效能較差(讀取不需要的欄位)
  2. 欄位順序可能變動
  3. 程式碼可讀性較低

欄位別名 AS

使用 AS 可以為欄位或資料表設定別名,讓結果更易讀。

-- 欄位別名
SELECT
    name AS 員工姓名,
    salary AS 月薪,
    salary * 12 AS 年薪
FROM employees;

-- AS 可以省略(但建議保留以提高可讀性)
SELECT name 員工姓名, salary 月薪 FROM employees;

DISTINCT 去除重複

DISTINCT 用來移除重複的資料列。

-- 查詢所有不重複的部門
SELECT DISTINCT department FROM employees;

-- 多欄位去重(組合後不重複)
SELECT DISTINCT department, job_title FROM employees;

注意:DISTINCT 會對所有選取的欄位進行去重判斷,而非單一欄位。

計算欄位與運算

SELECT 中可以進行數學運算和字串處理。

-- 數學運算
SELECT
    name,
    salary,
    salary * 1.05 AS 調薪後月薪,
    salary * 14 AS 年薪含獎金
FROM employees;

-- 字串連接(SQL Server)
SELECT
    name + ' - ' + department AS 員工資訊
FROM employees;

-- 字串連接(MySQL)
SELECT
    CONCAT(name, ' - ', department) AS 員工資訊
FROM employees;

WHERE 條件篩選技巧

比較運算子

WHERE 子句用來篩選符合條件的資料列。

運算子說明範例
=等於WHERE status = 'active'
<> 或 !=不等於WHERE status <> 'inactive'
>大於WHERE salary > 50000
<小於WHERE age < 30
>=大於等於WHERE score >= 60
<=小於等於WHERE price <= 1000
-- 查詢薪資超過 60000 的員工
SELECT name, salary
FROM employees
WHERE salary > 60000;

-- 查詢非行銷部的員工
SELECT name, department
FROM employees
WHERE department <> '行銷部';

LIKE 模糊查詢

LIKE 用於字串的模糊比對,搭配萬用字元使用。

萬用字元說明範例
%任意多個字元'王%' 匹配「王小明」「王大偉」
_單一字元'王_明' 匹配「王小明」但不匹配「王大明明」
-- 查詢姓王的員工
SELECT * FROM employees WHERE name LIKE '王%';

-- 查詢名字第二個字是「小」的員工
SELECT * FROM employees WHERE name LIKE '_小%';

-- 查詢 email 是 gmail 的員工
SELECT * FROM employees WHERE email LIKE '%@gmail.com';

-- 查詢職稱包含「工程師」的員工
SELECT * FROM employees WHERE job_title LIKE '%工程師%';

IN 與 NOT IN 列表查詢

IN 用來比對一組值,比多個 OR 更簡潔。

-- 查詢台北、台中、高雄的客戶
SELECT * FROM customers
WHERE city IN ('台北', '台中', '高雄');

-- 等同於
SELECT * FROM customers
WHERE city = '台北' OR city = '台中' OR city = '高雄';

-- 排除特定部門
SELECT * FROM employees
WHERE department NOT IN ('人資部', '財務部');

BETWEEN 範圍查詢

BETWEEN 用於範圍查詢,包含起始和結束值。

-- 查詢薪資在 40000 到 60000 之間的員工
SELECT name, salary
FROM employees
WHERE salary BETWEEN 40000 AND 60000;

-- 等同於
SELECT name, salary
FROM employees
WHERE salary >= 40000 AND salary <= 60000;

-- 日期範圍查詢
SELECT * FROM orders
WHERE order_date BETWEEN '2024-01-01' AND '2024-12-31';

IS NULL 空值處理

NULL 表示「沒有值」,不能用 = 來比較。

-- 查詢沒有填寫 email 的員工
SELECT * FROM employees WHERE email IS NULL;

-- 查詢有填寫 email 的員工
SELECT * FROM employees WHERE email IS NOT NULL;

-- 錯誤寫法(永遠不會有結果)
SELECT * FROM employees WHERE email = NULL;  -- ❌

重要觀念:NULL 不等於空字串 '',也不等於 0。NULL 代表「未知」或「不存在」。

邏輯運算子 AND、OR、NOT

組合多個條件時使用邏輯運算子。

-- AND:兩個條件都要成立
SELECT * FROM employees
WHERE department = '工程部' AND salary > 70000;

-- OR:至少一個條件成立
SELECT * FROM employees
WHERE department = '工程部' OR department = '產品部';

-- NOT:反轉條件
SELECT * FROM employees
WHERE NOT (salary < 50000);

-- 複合條件(注意括號優先順序)
SELECT * FROM employees
WHERE (department = '工程部' OR department = '產品部')
  AND salary > 60000;

插圖 2:WHERE 條件篩選流程圖

需要系統化學習 SQL?

根據調查,系統化學習 SQL 的人比自學摸索的人平均節省 60% 的學習時間,且更不容易遺漏重要觀念。

免費 SQL 語法速查表

我們整理了一份完整的 SQL 語法速查表 PDF,包含:

  • SELECT 完整語法結構
  • 所有比較運算子與範例
  • JOIN 類型圖解
  • 常用函數清單
  • 效能優化提示

這份速查表可以列印出來放在桌邊,隨時查閱。

CloudInsight SQL 培訓服務

如果你的團隊需要系統化的 SQL 培訓,CloudInsight 提供:

  • 客製化課程:依團隊程度設計課程內容
  • 實戰導向:使用真實資料進行練習
  • 課後支援:提供 30 天線上問答服務

👉 預約免費諮詢,了解企業培訓方案


聚合函數與 GROUP BY

五大聚合函數

聚合函數對一組資料進行計算,回傳單一結果。

函數功能範例注意事項
COUNT()計算筆數COUNT(*)COUNT(*) 包含 NULL,COUNT(欄位) 不含
SUM()加總SUM(salary)只能用於數值欄位
AVG()平均值AVG(score)自動忽略 NULL
MAX()最大值MAX(price)可用於字串(依字母排序)
MIN()最小值MIN(age)可用於日期
-- 統計員工總數
SELECT COUNT(*) AS 員工總數 FROM employees;

-- 計算平均薪資
SELECT AVG(salary) AS 平均薪資 FROM employees;

-- 多個聚合函數同時使用
SELECT
    COUNT(*) AS 員工數,
    SUM(salary) AS 薪資總和,
    AVG(salary) AS 平均薪資,
    MAX(salary) AS 最高薪資,
    MIN(salary) AS 最低薪資
FROM employees;

GROUP BY 分組統計

GROUP BY 將資料依指定欄位分組,再對每組進行聚合計算。

-- 計算各部門的員工人數和平均薪資
SELECT
    department,
    COUNT(*) AS 員工人數,
    AVG(salary) AS 平均薪資
FROM employees
GROUP BY department;

-- 多欄位分組
SELECT
    department,
    job_title,
    COUNT(*) AS 人數
FROM employees
GROUP BY department, job_title;

重要規則:SELECT 中的非聚合欄位,必須出現在 GROUP BY 中。

-- ❌ 錯誤:name 不在 GROUP BY 中
SELECT department, name, COUNT(*)
FROM employees
GROUP BY department;

-- ✅ 正確
SELECT department, COUNT(*)
FROM employees
GROUP BY department;

HAVING 分組條件

HAVING 用來篩選分組後的結果,不能用 WHERE 替代。

-- 找出員工人數超過 5 人的部門
SELECT department, COUNT(*) AS 員工人數
FROM employees
GROUP BY department
HAVING COUNT(*) > 5;

-- 找出平均薪資超過 60000 的部門
SELECT department, AVG(salary) AS 平均薪資
FROM employees
GROUP BY department
HAVING AVG(salary) > 60000;

WHERE vs HAVING 差異

這是常見的面試考題,務必搞清楚。

比較項目WHEREHAVING
執行時機GROUP BY 之前GROUP BY 之後
篩選對象個別資料列分組結果
能否使用聚合函數不能可以
-- 先用 WHERE 篩選資料,再分組統計
SELECT department, AVG(salary) AS 平均薪資
FROM employees
WHERE hire_date >= '2020-01-01'  -- 篩選 2020 年後入職的員工
GROUP BY department
HAVING AVG(salary) > 50000;      -- 篩選平均薪資超過 50000 的部門

排序與分頁

ORDER BY 排序

ORDER BY 用來對結果進行排序。

-- 依薪資由高到低排序
SELECT name, salary
FROM employees
ORDER BY salary DESC;

-- 依薪資由低到高排序(ASC 是預設值,可省略)
SELECT name, salary
FROM employees
ORDER BY salary ASC;

-- 多欄位排序
SELECT name, department, salary
FROM employees
ORDER BY department ASC, salary DESC;
-- 先依部門升序,同部門內再依薪資降序

排序關鍵字:

  • ASC:升序(Ascending),由小到大,預設值
  • DESC:降序(Descending),由大到小

LIMIT 與 OFFSET 分頁

LIMIT 限制回傳的資料筆數,常用於分頁。

-- 取前 10 筆(MySQL、PostgreSQL、SQLite)
SELECT * FROM employees LIMIT 10;

-- 取第 11-20 筆(跳過前 10 筆)
SELECT * FROM employees LIMIT 10 OFFSET 10;

-- 簡寫語法(MySQL)
SELECT * FROM employees LIMIT 10, 10;  -- LIMIT 偏移量, 筆數

SQL Server 的分頁語法不同:

-- SQL Server 2012+
SELECT * FROM employees
ORDER BY id
OFFSET 10 ROWS
FETCH NEXT 10 ROWS ONLY;

-- SQL Server 較舊版本
SELECT TOP 10 * FROM employees;

分頁查詢範例

實務上的分頁通常這樣實作:

-- 假設每頁顯示 20 筆,查詢第 3 頁
-- 第 3 頁 = 跳過前 40 筆((3-1) * 20)

SELECT *
FROM products
ORDER BY created_at DESC
LIMIT 20 OFFSET 40;

JOIN 多表連接概述

當資料分散在多個資料表時,需要用 JOIN 來合併。

JOIN 類型總覽

JOIN 類型說明使用時機
INNER JOIN只回傳兩邊都有匹配的資料最常用,只要有關聯的資料
LEFT JOIN回傳左表所有資料要保留左表所有資料,即使右表沒有匹配
RIGHT JOIN回傳右表所有資料較少使用,可用 LEFT JOIN 改寫
FULL OUTER JOIN回傳兩邊所有資料需要兩表的完整聯集
CROSS JOIN笛卡爾積需要所有組合(較少用)

INNER JOIN 基本範例

-- 查詢訂單及對應的客戶名稱
SELECT
    orders.order_id,
    orders.order_date,
    customers.name AS customer_name
FROM orders
INNER JOIN customers ON orders.customer_id = customers.id;

-- 使用表格別名簡化
SELECT
    o.order_id,
    o.order_date,
    c.name AS customer_name
FROM orders o
INNER JOIN customers c ON o.customer_id = c.id;

LEFT JOIN 範例

-- 查詢所有客戶及其訂單(包含沒有訂單的客戶)
SELECT
    c.name,
    o.order_id,
    o.total_amount
FROM customers c
LEFT JOIN orders o ON c.id = o.customer_id;

沒有訂單的客戶,order_id 和 total_amount 會顯示 NULL。

JOIN 是 SQL 進階查詢的核心技能,完整的圖解教學請參考 SQL JOIN 完整教學指南

插圖 3:SQL JOIN 類型 Venn Diagram 圖解

實戰範例與練習題

範例資料庫結構

假設我們有以下三個資料表:

employees(員工表)

欄位類型說明
idINT員工編號
nameVARCHAR姓名
department_idINT部門編號
salaryDECIMAL薪資
hire_dateDATE入職日期

departments(部門表)

欄位類型說明
idINT部門編號
nameVARCHAR部門名稱
manager_idINT主管編號

orders(訂單表)

欄位類型說明
idINT訂單編號
employee_idINT負責員工
amountDECIMAL訂單金額
order_dateDATE訂單日期

練習題與解答

題目 1:查詢薪資前 5 高的員工姓名和薪資

SELECT name, salary
FROM employees
ORDER BY salary DESC
LIMIT 5;

題目 2:查詢各部門的員工人數和平均薪資

SELECT
    d.name AS 部門名稱,
    COUNT(e.id) AS 員工人數,
    ROUND(AVG(e.salary), 0) AS 平均薪資
FROM departments d
LEFT JOIN employees e ON d.id = e.department_id
GROUP BY d.id, d.name;

題目 3:找出 2024 年訂單金額超過 100 萬的員工

SELECT
    e.name,
    SUM(o.amount) AS 總訂單金額
FROM employees e
INNER JOIN orders o ON e.id = o.employee_id
WHERE o.order_date BETWEEN '2024-01-01' AND '2024-12-31'
GROUP BY e.id, e.name
HAVING SUM(o.amount) > 1000000
ORDER BY 總訂單金額 DESC;

題目 4:查詢沒有任何訂單的員工

SELECT e.name
FROM employees e
LEFT JOIN orders o ON e.id = o.employee_id
WHERE o.id IS NULL;

SQL 語法速查表

SELECT 語法結構

SELECT [DISTINCT] 欄位1, 欄位2, ...
FROM 資料表
[JOIN 其他表 ON 條件]
[WHERE 篩選條件]
[GROUP BY 分組欄位]
[HAVING 分組條件]
[ORDER BY 排序欄位 [ASC|DESC]]
[LIMIT 筆數 [OFFSET 偏移量]]

常用運算子速查

類型運算子
比較=, <>, >, <, >=, <=
範圍BETWEEN...AND
列表IN, NOT IN
模糊LIKE (%, _)
空值IS NULL, IS NOT NULL
邏輯AND, OR, NOT

聚合函數速查

函數用途
COUNT(*)計算所有列數
COUNT(欄位)計算非 NULL 的列數
SUM(欄位)數值加總
AVG(欄位)數值平均
MAX(欄位)最大值
MIN(欄位)最小值

想學習更多 SQL 函數,請參考 SQL 函數完整指南


常見問題 FAQ

Q1: SQL SELECT 可以選取所有欄位嗎?

可以,使用 SELECT * 會選取資料表中的所有欄位。但在正式環境中不建議這樣做,因為:(1)效能較差,會讀取不必要的資料;(2)如果資料表結構改變,可能導致程式出錯;(3)程式碼可讀性較低。建議明確列出需要的欄位。

Q2: WHERE 和 HAVING 有什麼差別?

WHERE 在 GROUP BY 之前執行,用來篩選個別資料列,不能使用聚合函數。HAVING 在 GROUP BY 之後執行,用來篩選分組結果,可以使用聚合函數。例如:WHERE salary > 50000(篩選個人薪資)vs HAVING AVG(salary) > 50000(篩選部門平均薪資)。

Q3: SQL GROUP BY 一定要配合聚合函數嗎?

不一定,但 GROUP BY 通常會搭配聚合函數使用才有意義。如果只是要去除重複資料,可以使用 DISTINCT。GROUP BY 的主要目的是將資料分組後進行統計計算,如果不使用聚合函數,每組只會回傳一筆資料,結果可能不如預期。


延伸閱讀

掌握基礎語法後,建議繼續學習以下主題:

基礎進階:

進階技巧:

實務應用:


提升團隊 SQL 能力

一個熟練 SQL 的資料分析師,產出效率是初學者的 5-10 倍。投資團隊的 SQL 培訓,是提升整體生產力最有效的方式之一。

CloudInsight SQL 企業培訓

  • 初階課程:SELECT、WHERE、JOIN、GROUP BY 完整教學
  • 進階課程:子查詢、視窗函數、效能優化
  • 實戰工作坊:使用真實商業資料進行練習
  • 課後輔導:30 天線上問答支援

培訓成效保證

  • 完課後立即能獨立撰寫 80% 日常查詢
  • 提供課程錄影,可反覆複習
  • 結業測驗通過率 95% 以上

👉 預約免費諮詢,為團隊規劃最適合的 SQL 培訓方案


參考資料

  1. Microsoft, "Transact-SQL Reference" (2024)
  2. MySQL Documentation, "SELECT Statement" (2024)
  3. PostgreSQL Documentation, "SQL Commands" (2024)
  4. W3Schools, "SQL Tutorial" (2024)
  5. SQLZoo, "SQL Teaching" (2024)

需要專業的雲端建議?

無論您正在評估雲平台、優化現有架構,或尋找節費方案,我們都能提供協助

預約免費諮詢

相關文章