SELECT 是 SQL 最核心、使用頻率最高的指令。從簡單的「查所有」到複雜的多表連接、子查詢、窗口函數,掌握 SELECT 的完整語法與 PHP 驅動的三種獲取模式(關聯陣列、數值索引、雙模式),是後端開發的必修課。
SELECT [DISTINCT] column_list FROM table_name [WHERE condition] [GROUP BY column_list] [HAVING condition] [ORDER BY column_list [ASC|DESC]] [LIMIT [offset,] row_count];
column_list:* 代表所有欄位,生產環境建議明確列出所需欄位。DISTINCT:去除重複行。OFFSET M LIMIT N:跳過 M 行,取 N 行(分頁核心)。LIMIT N OFFSET M 同義。mysql> SELECT * FROM runoob_tbl; +-------------+----------------+-----------------+-----------------+ | runoob_id | runoob_title | runoob_author | submission_date | +-------------+----------------+-----------------+-----------------+ | 1 | Learn PHP | John Poul | 2007-05-21 | | 2 | Learn MySQL | Abdul S | 2007-05-21 | | 3 | JAVA Tutorial | Sanjay | 2007-05-21 | +-------------+----------------+-----------------+-----------------+
| 函數/常數 | 返回結構 | 索引方式 | 記憶體佔用 | 適用場景 |
|---|---|---|---|---|
mysqli_fetch_assoc() | 關聯陣列 | 欄位名 $row['col'] | 中等 | 業務代碼可讀性優先、欄位名固定 |
mysqli_fetch_array($result, MYSQLI_NUM) | 數值索引陣列 | 位置 $row[0] | 最低 | 高效能、大量資料、欄位順序固定 |
mysqli_fetch_array($result, MYSQLI_BOTH) | 雙模式(預設) | 兩者皆可 | 最高 | 兼容舊代碼、需同時按名稱/位置存取 |
<?php
$sql = 'SELECT runoob_id, runoob_title, runoob_author, submission_date FROM runoob_tbl';
$retval = mysqli_query($conn, $sql);
while ($row = mysqli_fetch_assoc($retval)) {
echo "ID: {$row['runoob_id']} <br>";
echo "Title: {$row['runoob_title']} <br>";
echo "Author: {$row['runoob_author']} <br>";
echo "Date: {$row['submission_date']} <br><hr>";
}
mysqli_free_result($retval); // 釋放記憶體
?>
<?php
while ($row = mysqli_fetch_array($retval, MYSQLI_NUM)) {
echo "ID: {$row[0]} <br> Title: {$row[1]} <br> Author: {$row[2]} <br> Date: {$row[3]} <br><hr>";
}
?>
<?php
while ($row = mysqli_fetch_array($retval)) { // 預設 MYSQLI_BOTH
echo "ID: {$row['runoob_id']} / {$row[0]} <br>"; // 兩種寫法皆可
}
?>
-- 第 1 頁,每頁 10 筆 SELECT * FROM runoob_tbl ORDER BY runoob_id LIMIT 10 OFFSET 0; -- 第 2 頁 SELECT * FROM runoob_tbl ORDER BY runoob_id LIMIT 10 OFFSET 10; -- 簡寫:LIMIT offset, count SELECT * FROM runoob_tbl ORDER BY runoob_id LIMIT 10, 10;
結果集佔用客戶端記憶體,大結果集未釋放會導致 PHP 記憶體耗盡。循環讀取結束後立即釋放:
<?php
$retval = mysqli_query($conn, $sql);
while ($row = mysqli_fetch_assoc($retval)) { /* ... */ }
mysqli_free_result($retval); // 關鍵!
mysqli_close($conn);
?>
INDEX (a,b) 可滿足 SELECT a,b FROM t WHERE a=1 無需回表。LIMIT 100000, 10 極慢。改用 WHERE id > last_max_id LIMIT 10(游標分頁)或延遲關聯。mysqli_prepare / PDO::prepare)。SELECT 是讀取資料的起點,也是效能調優的主戰場。熟練掌握語法變體、選對獲取模式、善用 LIMIT 分頁、嚴守記憶體釋放與防注入,讓每一次查詢都精準、高效、安全。