首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫

MySQL SELECT 查詢完全指南:從基礎語法到多表聯查與分組統計實戰

     編輯:MySQL 資料庫相關知識

前言:SELECT 是 SQL 的靈魂,掌握它掌握數據洞察力

SELECT 是使用頻率最高、功能最豐富的 SQL 指令。本文按標準子句順序(SELECT → FROM → WHERE → GROUP BY → HAVING → ORDER BY → LIMIT)系統講解核心用法,並以經典 pet、event 表為例,演示條件過濾、排序、分組聚合、多表聯查、自聯查等實戰技巧。

一、SELECT 完整語法骨架

SELECT select_list          -- 選擇列/運算式
FROM table_list             -- 來源表(可多表)
WHERE primary_constraint    -- 行級過濾條件
GROUP BY grouping_columns   -- 分組依據
HAVING secondary_constraint -- 組級過濾條件
ORDER BY sorting_columns    -- 結果排序
LIMIT count [OFFSET offset] -- 結果限制

順序固定不可亂;除 SELECT、select_list 外皆可選。MySQL 允許無 FROM 純運算:SELECT (2+3*4.5)/2.5;

二、基礎查詢:全表、特定行、特定列

-- 全表全欄
SELECT * FROM pet;

-- 條件過濾特定行
SELECT * FROM pet WHERE name = 'Bowser';

-- 投影特定列
SELECT name, birth FROM pet WHERE owner = 'Gwen';

三、運算式計算與內建函數

-- 算術運算
SELECT death - birth AS days_lived FROM pet WHERE name='Bowser';

-- 字串/日期函數
SELECT CONCAT(name, '(', species, ')') AS desc FROM pet;
SELECT DATEDIFF(death, birth) FROM pet WHERE death IS NOT NULL;

四、條件查詢:WHERE 子句深度解析

運算符速查

類別運算符範例
算術+ - * / %price * 1.05
比較= != <> < <= > >=birth >= '1998-01-01'
範圍/集合BETWEEN ... AND ... / IN (...) / NOT INid BETWEEN 1 AND 100
模糊匹配LIKE / NOT LIKEname LIKE 'B%'
空值判斷IS NULL / IS NOT NULLdeath IS NULL
邏輯AND / OR / NOTspecies='dog' AND sex='f'
正則REGEXP / RLIKEname REGEXP '^[A-C]'

複合條件與括號分組

(species = 'cat' AND sex = 'm') OR (species = 'dog' AND sex = 'f')

字串比較預設不區分大小寫(依排序規則),加 BINARY 強制區分。

五、排序:ORDER BY 多欄位混排

-- 單欄升序(預設)
SELECT name, birth FROM pet ORDER BY birth;

-- 降序
SELECT name, birth FROM pet ORDER BY birth DESC;

-- 多欄:先按種類升序,同種類內按出生降序
SELECT name, species, birth FROM pet ORDER BY species, birth DESC;

注意:DESC 僅作用於緊前欄位;TEXT/BLOB 不可排序。

六、分組統計:GROUP BY + 聚合函數

核心聚合函數

  • COUNT(*) / COUNT(col) — 行數 / 非 NULL 值數
  • SUM(col), AVG(col), MIN(col), MAX(col)
  • GROUP_CONCAT(col SEPARATOR ',') — 組內值串聯 (MySQL 特有)

基本分組

-- 每位主人寵物數
SELECT owner, COUNT(*) FROM pet GROUP BY owner;

-- 每種寵物數量
SELECT species, COUNT(*) FROM pet GROUP BY species;

多欄分組

SELECT species, sex, COUNT(*) FROM pet GROUP BY species, sex;

HAVING 過濾分組結果

-- 只顯示擁有 2 隻以上寵物的主人
SELECT owner, COUNT(*) AS cnt FROM pet GROUP BY owner HAVING cnt > 2;

WHERE vs HAVING:WHERE 過濾原始行(聚合前),HAVING 過濾分組結果(聚合後);WHERE 不可用聚合函數,HAVING 可用。

七、多表聯查:JOIN 核心模式

內聯 (INNER JOIN) — 交集

SELECT pet.name, (TO_DAYS(event.date)-TO_DAYS(pet.birth))/365 AS age, event.remark
FROM pet INNER JOIN event ON pet.name = event.name
WHERE event.type = 'litter';

自聯 — 表與自身關聯

-- 寵物配對:同種類、雌雄配對
SELECT p1.name, p1.sex, p2.name, p2.sex, p1.species
FROM pet AS p1 INNER JOIN pet AS p2
  ON p1.species = p2.species AND p1.sex = 'f' AND p2.sex = 'm';

別名 (AS) 消除欄位歧義,提升可讀性。

左/右外聯 (LEFT/RIGHT JOIN) — 保留主/從表所有行

SELECT owner, pet.name FROM owner LEFT JOIN pet ON owner.id = pet.owner_id;
-- 無寵物主人也會列出,pet.name 為 NULL

八、LIMIT 分頁與優化

-- 前 10 筆
SELECT * FROM pet LIMIT 10;

-- 分頁:第 3 頁,每頁 10 筆
SELECT * FROM pet LIMIT 10 OFFSET 20;
-- 或
SELECT * FROM pet LIMIT 20, 10;

深分頁效能陷阱:LIMIT 1000000, 10 需掃描 100 萬行再丟棄。優化:WHERE id > last_max_id ORDER BY id LIMIT 10 (游標式分頁)。

九、實戰避坑清單

  1. SELECT * 禁止生產環境用:增加網傳、防覆蓋索引、Schema 變更衝擊。
  2. WHERE 盡量用索引欄位,避免函數包裹(WHERE DATE(created_at)=... → WHERE created_at >= ... AND created_at < ...)。
  3. OR 連接不同索引欄位常導致全表掃描,改 UNION ALL 或重構。
  4. GROUP BY 隱含排序 (MySQL 5.7 前),5.7+ 需顯式 ORDER BY 保證順序。
  5. 大表 COUNT(*) 極慢,用近似值 EXPLAIN Rows、觸發器維護計數表、或 SELECT COUNT(*) FROM information_schema.TABLES WHERE TABLE_NAME='t' (MyISAM 精確/InnoDB 估算)。
  1. 上一篇文章:
  2. 下一篇文章:
Copyright © 程式碼之家 All Rights Reserved