SUBSTRING 是 SQL Server 擷取字串片段的核心函數,語法:SUBSTRING(expression, start, length)。本文從基礎用法進階至搭配 CHARINDEX 動態定位起始/長度,解決「起始位置不固定、長度不固定」的實務擷取問題。
SELECT SUBSTRING('abdcsef', 1, 3); -- 回傳 'abd'
-- start=1 從第 1 字元開始,length=3 擷取 3 字元
跨資料庫對照:MySQL SUBSTR/SUBSTRING、Oracle SUBSTR、SQL Server SUBSTRING。
資料欄位 roomno 值如:3單元201室、12單元1005室,需擷取中間房間號 201、1005。起始位置 (「單元」後)、結束位置 (「室」前) 皆不固定。

SELECT
roomno,
SUBSTRING(
roomno,
CHARINDEX('單元', roomno) + 2, -- 起始:「單元」後 2 字元 (跳過「單元」二字)
CHARINDEX('室', roomno) - CHARINDEX('單元', roomno) - 2 -- 長度:「室」位置 - 「單元」位置 - 2
) AS room_number
FROM PROPERTY_room
WHERE roomno LIKE '%單元%室%';

| 函數 | 用途 | 範例 |
|---|---|---|
| CHARINDEX('搜尋字串', 目標字串, [起始位置]) | 回傳搜尋字串首次出現位置 (1-based),找不到回傳 0 | CHARINDEX('單元', '3單元201室') = 2 |
| SUBSTRING(字串, 起始, 長度) | 擷取子字串 | SUBSTRING('3單元201室', 4, 3) = '201' |
| LEN(字串) | 字串長度 | LEN('201') = 3 |
| 需求 | SQL 寫法 |
|---|---|
| 擷取最後 N 字元 | RIGHT(str, N) 或 SUBSTRING(str, LEN(str)-N+1, N) |
| 擷取第一個分隔符前內容 | SUBSTRING(str, 1, CHARINDEX(',', str)-1) (需處理找不到情況) |
| 擷取最後一個分隔符後內容 | SUBSTRING(str, CHARINDEX('/', REVERSE(str)) ...) 配合 REVERSE |
| 移除首尾空白再擷取 | SUBSTRING(LTRIM(RTRIM(str)), start, length) |
| 多段擷取組合 | SUBSTRING(str, p1, l1) + '-' + SUBSTRING(str, p2, l2) |
SUBSTRING、CHARINDEX 在 WHERE/JOIN 條件中使用會導致掃描,無法使用索引搜尋。SELECT
roomno,
CASE
WHEN CHARINDEX('單元', roomno) > 0 AND CHARINDEX('室', roomno) > 0
THEN SUBSTRING(roomno, CHARINDEX('單元', roomno)+2, CHARINDEX('室', roomno)-CHARINDEX('單元', roomno)-2)
ELSE NULL
END AS room_number
FROM PROPERTY_room;
掌握 SUBSTRING + CHARINDEX 組合,即可解決絕大多數「非固定位置/長度」字串擷取需求。