Logo

新人日誌

首頁關於我部落格

新人日誌

Logo

網站會不定期發佈技術筆記、職場心得相關的內容,歡迎關注本站!

網站
首頁關於我部落格
部落格
分類系列文

© 新人日誌. All rights reserved. 2020-present.

資料庫表單與資料操作:用 SELECT 讀取資料的完整指南

最後更新:2026年1月14日資料庫

前幾篇介紹完新增、修改、刪除之後,這篇來講「讀取資料」。

你可能會想:讀取不是最簡單的嗎?為什麼放到後面才講?

其實讀取的操作本身不難,但在實際工作中,讀取資料的時間會比你想像中還要多。

因為你不是單純把資料讀出來就好,通常還需要做各種資料整理——這部分會在下一篇詳細說明。

這篇文章會先帶你了解 SELECT 的基本用法,以及背後的運作原理。

查詢的兩個核心問題:欄位與資料列

想像一個情境:老闆跟你說「我要會員資料」。

光這樣講是不夠的,你還需要知道:

  1. 要取哪些欄位? 是電話、信箱、還是姓名?
  2. 要取哪些會員? 是全部會員,還是符合特定條件的會員?

這兩個問題,對應到讀取資料時的兩個核心概念:選擇「欄位」和篩選「資料列」。

「要取哪些欄位」就是在決定要取出電話、信箱、還是姓名,甚至可以是計算後的結果,像是單價乘以數量。

「要取哪些會員」就是在決定要取出全部會員,還是符合某個條件的會員,像是年齡大於 30 歲的人。

在 SQL 中,選擇欄位用 SELECT,篩選資料列用 WHERE,另外還需要用 FROM 指定要從哪張表單取資料。

完整的查詢語法長這樣:

SELECT 欄位或計算結果
FROM 表單名稱
WHERE 篩選條件

雖然語法是這樣寫,但資料庫實際執行的順序是 FROM → WHERE → SELECT。

所以接下來我們按照執行順序來說明。

在開始之前,先假設我們有一張「會員」表單:

ID姓名
1王小明
2李小華
姓王
名小明
姓李
名小華

接下來的範例都會用這張表單來示範。

FROM:指定要從哪張表單取資料

FROM 後面放的是表單名稱。

這很直覺——你要讀資料,總要告訴資料庫是哪一張表單吧。

FROM 會員

WHERE:篩選符合條件的資料列

WHERE 用來設定篩選條件。

只有符合條件的資料列才會被取出來。

FROM 會員
WHERE 姓 = '王'

這樣就只會取出姓王的會員。

SELECT:挑出你要的欄位

SELECT 後面放的是你要「取出」的東西。

可以是欄位名稱,也可以是計算結果。

加上 SELECT 之後,就是完整的查詢語法了:

SELECT 姓, 名
FROM 會員
WHERE 姓 = '王'

這樣會取出會員表單中,姓王的人的「姓」和「名」兩個欄位。

取出計算結果並取別名

除了取出欄位,SELECT 也可以取出計算後的結果。

例如,我們想把「姓」和「名」串在一起變成「全名」:

SELECT CONCAT(姓, 名) AS 全名
FROM 會員
WHERE 姓 = '王'

CONCAT() 是把字串連接起來的函數,括號裡放你要連接的欄位,用逗號隔開。

這裡 CONCAT(姓, 名) 會把「王」和「小明」接在一起,變成「王小明」。

AS 全名 是給這個計算結果取一個別名。

如果不取別名,資料庫會自動產生一個名稱,像是 CONCAT(姓, 名) 或一串看不懂的代號。

取了別名之後,結果的欄位名稱就會顯示成「全名」,清楚易懂。

建議:只要是計算結果,一定要給別名。

為什麼語法順序和執行順序不同?

看完 FROM、WHERE、SELECT 之後,你可能會覺得奇怪:我們思考的順序是「先選表單 → 再篩選 → 最後挑欄位」,但 SQL 的寫法順序卻是 SELECT → FROM → WHERE,剛好相反。

這是因為 SQL 在 1970 年代設計時,目標是讓語法看起來像英文句子,降低使用門檻。

用英文來讀的話:「Select these columns from this table where this condition is true.」

翻成中文就是:「選取這些欄位,從這張表,當滿足這個條件。」

這種結構把「結果」放在最前面,讓你一眼就能看到這個查詢最終要輸出什麼資料。

但資料庫引擎實際執行時,還是按照邏輯順序來處理:

  1. FROM:先確定要從哪張表抓資料
  2. WHERE:進行篩選,剔除不符合條件的資料列
  3. SELECT:從剩下的資料中,挑選出指定的欄位

所以你的思考邏輯是對的,那正是資料庫實際運作的步驟。

這也解釋了一個常見的錯誤:為什麼在 WHERE 中不能使用 SELECT 定義的別名。

SELECT CONCAT(姓, 名) AS 全名
FROM 會員
WHERE 全名 = '王小明'  -- 這會報錯!

這段語法會報錯。

為什麼?

因為資料庫的執行順序是 FROM → WHERE → SELECT。

當資料庫執行到 WHERE 的時候,SELECT 根本還沒開始處理。

也就是說,CONCAT(姓, 名) AS 全名 這個別名還不存在,資料庫不知道「全名」是什麼。

如果要篩選全名,你必須在 WHERE 中重新寫一次完整的計算:

SELECT CONCAT(姓, 名) AS 全名
FROM 會員
WHERE CONCAT(姓, 名) = '王小明'  -- 這樣才對

這看起來有點重複,但這就是 SQL 執行順序造成的限制。

WHERE 篩選的運作原理

這裡要解釋一個很重要的概念。

當資料庫執行 WHERE 篩選時,它是這樣運作的:

  1. 移動到第一筆資料
  2. 檢查:這筆資料符合條件嗎?符合就留下,不符合就跳過
  3. 移動到下一筆資料
  4. 重複步驟 2 和 3,直到檢查完所有資料
  5. 把所有符合條件的資料回傳

關鍵重點:每次判斷都只看「當下這一筆」資料。

理解這個原理之後,你就會知道為什麼 WHERE 不能用聚合函數。

因為 WHERE 在檢查每一筆資料時,只能看到「當下這一筆」的內容。

它不知道總共有幾筆資料、不知道其他筆的數值是多少,也沒辦法把多筆資料加起來。

所以像 SUM、COUNT、AVG 這類需要「看過全部資料才能算出結果」的運算,在 WHERE 裡面是做不到的。

以下這些運算在 WHERE 中都不能用:

運算為什麼不能用
SUM(加總)需要把多筆資料加起來
COUNT(計數)需要數有幾筆資料
AVG(平均)需要把全部加起來再除以筆數
MAX / MIN(最大 / 最小值)需要跟其他筆資料比較
為什麼不能用需要把多筆資料加起來
為什麼不能用需要數有幾筆資料
為什麼不能用需要把全部加起來再除以筆數
為什麼不能用需要跟其他筆資料比較

這些都需要「看到其他筆資料」才能計算,但 WHERE 一次只能看一筆。

那怎麼辦?

這個問題會在「資料整理」的文章解決,那裡會教你用 GROUP BY 和 HAVING。

用 * 和省略 WHERE 取得全部資料

有時候你不需要篩選,就是要全部的資料。

* 是萬用字元,代表「所有欄位」。

省略 WHERE,代表「不篩選,取所有資料列」。

所以當你想把整張表單的資料全部取出來,可以這樣寫:

SELECT *
FROM 會員

這會取出會員表單中的所有欄位、所有資料列。

用 Primary Key 查詢特定資料

假設你就是要找 ID 為 1 的那個會員。

建議用 Primary Key(主鍵)來篩選:

SELECT *
FROM 會員
WHERE ID = 1

為什麼用 ID 而不是用姓名?

因為可能有兩個人都叫王小明,但 ID 是唯一的。

用 Primary Key 可以確保只會取到那一筆資料。

SELECT 結果作為子查詢(Subquery)

這是一個非常重要的觀念。

當你執行一段 SELECT 查詢後,資料庫會回傳一個結果。

這個結果長什麼樣子?它有欄位名稱、有資料內容,結構上跟一張表單一模一樣。

例如,執行這段查詢:

SELECT ID, CONCAT(姓, 名) AS 全名
FROM 會員
WHERE 姓 = '王'

會得到這樣的結果:

ID全名
1王小明
全名王小明

這個結果本身就像是一張「臨時的表單」,只是它沒有被存在資料庫裡,只存在於這次查詢的過程中。

既然它像一張表單,那我們能不能把它當成表單來用?

答案是可以的。這就是「子查詢」的概念。

子查詢放在 FROM

SELECT *
FROM (
    SELECT ID, CONCAT(姓, 名) AS 全名
    FROM 會員
) AS 臨時表

括號裡面的 SELECT 結果,被當成一張表單來使用。

執行結果:

ID全名
1王小明
2李小華
全名王小明
全名李小華

子查詢放在 WHERE

假設你想找「跟第一個會員同姓的人」:

先看括號裡的子查詢:

SELECT 姓
FROM 會員
WHERE ID = 1

執行結果:

姓
王

這個子查詢會回傳「王」這個值。

接著,外層查詢把這個結果拿來當作篩選條件:

SELECT 姓, 名
FROM 會員
WHERE 姓 = (
    SELECT 姓
    FROM 會員
    WHERE ID = 1
)

執行結果:

姓名
王小明
名小明

這裡的邏輯是:

  1. 先執行括號裡的查詢,取得 ID = 1 的會員的姓(結果是「王」)
  2. 外層查詢再用這個結果來篩選,找出所有姓王的人

注意:括號裡的查詢要用小括號包起來,表示它是「一包東西」。

小結

這篇文章介紹了 SELECT 的基本用法:

  • SELECT:指定要取出的欄位或計算結果,可以用 AS 取別名
  • FROM:指定要從哪張表單取資料
  • WHERE:設定篩選條件,只取符合條件的資料列
  • * 萬用字元:代表所有欄位
  • 省略 WHERE:代表取所有資料列
  • WHERE 的限制:只能處理單筆資料的判斷,不能用聚合函數
  • SELECT 結果是臨時表單:可以被其他查詢引用,放在 FROM 或 WHERE 中

記住這個核心概念:讀取資料就是在回答「要哪些欄位」和「要哪些資料列」這兩個問題。

目前還沒有留言,成為第一個留言的人吧!

發表留言

留言將在審核後顯示。

資料庫

目錄

  • 查詢的兩個核心問題:欄位與資料列
  • FROM:指定要從哪張表單取資料
  • WHERE:篩選符合條件的資料列
  • SELECT:挑出你要的欄位
  • 取出計算結果並取別名
  • 為什麼語法順序和執行順序不同?
  • WHERE 篩選的運作原理
  • 用 * 和省略 WHERE 取得全部資料
  • 用 Primary Key 查詢特定資料
  • SELECT 結果作為子查詢(Subquery)
  • 子查詢放在 FROM
  • 子查詢放在 WHERE
  • 小結