1. 程式人生 > >吳裕雄 11-MySQL查詢資料

吳裕雄 11-MySQL查詢資料

以下為在MySQL資料庫中查詢資料通用的 SELECT 語法:
SELECT column_name,column_name
FROM table_name
[WHERE Clause]
[LIMIT N][ OFFSET M]
查詢語句中你可以使用一個或者多個表,表之間使用逗號(,)分割,
並使用WHERE語句來設定查詢條件。
SELECT 命令可以讀取一條或者多條記錄。
你可以使用星號(*)來代替其他欄位,SELECT語句會返回表的所有欄位資料
你可以使用 WHERE 語句來包含任何條件。
你可以使用 LIMIT 屬性來設定返回的記錄數。
你可以通過OFFSET指定SELECT語句開始查詢的資料偏移量。預設情況下偏移量為0。

以下例項將返回資料表 runoob_tbl 的所有記錄:
select * from runoob_tbl;

使用PHP指令碼來獲取資料
使用 PHP 函式的 mysqli_query() 及 SQL SELECT 命令來獲取資料。
該函式用於執行 SQL 命令,然後通過 PHP 函式 mysqli_fetch_array()
來使用或輸出所有查詢的資料。
mysqli_fetch_array() 函式從結果集中取得一行作為關聯陣列,或數字陣列,
或二者兼有 返回根據從結果集取得的行生成的陣列,如果沒有更多行則返回 false。
以下例項為從資料表 runoob_tbl 中讀取所有記錄。
例項
嘗試以下例項來顯示資料表 runoob_tbl 的所有記錄。
<?php
$dbhost = 'localhost:3306'; // mysql伺服器主機地址
$dbuser = 'root'; // mysql使用者名稱
$dbpass = '123456'; // mysql使用者名稱密碼
$conn = mysqli_connect($dbhost, $dbuser, $dbpass);
if(! $conn )
{
die('連線失敗: ' . mysqli_error($conn));
}
// 設定編碼,防止中文亂碼
mysqli_query($conn , "set names utf8");

$sql = 'SELECT runoob_id, runoob_title,
runoob_author, submission_date
FROM runoob_tbl';
mysqli_select_db( $conn, 'RUNOOB' );
$retval = mysqli_query( $conn, $sql );
if(! $retval )
{
die('無法讀取資料: ' . mysqli_error($conn));
}
echo '<h2>菜鳥教程 mysqli_fetch_array 測試<h2>';
echo '<table border="1"><tr><td>教程 ID</td><td>標題</td><td>作者</td><td>提交日期</td></tr>';
while($row = mysqli_fetch_array($retval, MYSQLI_ASSOC))
{
echo "<tr><td> {$row['runoob_id']}</td> ".
"<td>{$row['runoob_title']} </td> ".
"<td>{$row['runoob_author']} </td> ".
"<td>{$row['submission_date']} </td> ".
"</tr>";
}
echo '</table>';
mysqli_close($conn);
?>

注意:記住如果你需要在字串中使用變數,請將變數置於花括號。
在上面的例子中,PHP mysqli_fetch_array() 函式第二個引數為 MYSQLI_ASSOC,
設定該引數查詢結果返回關聯陣列,你可以使用欄位名稱來作為陣列的索引。
PHP 提供了另外一個函式 mysqli_fetch_assoc(), 該函式從結果集中取得一行作為
關聯陣列。 返回根據從結果集取得的行生成的關聯陣列,如果沒有更多行,則返回 false。

例項
嘗試以下例項,該例項使用了 mysqli_fetch_assoc() 函式來輸出資料表 runoob_tbl 的所有記錄:

使用 mysqli_fetch_assoc 獲取資料:
<?php
$dbhost = 'localhost:3306'; // mysql伺服器主機地址
$dbuser = 'root'; // mysql使用者名稱
$dbpass = '123456'; // mysql使用者名稱密碼
$conn = mysqli_connect($dbhost, $dbuser, $dbpass);
if(! $conn )
{
die('連線失敗: ' . mysqli_error($conn));
}
// 設定編碼,防止中文亂碼
mysqli_query($conn , "set names utf8");
$sql = 'SELECT runoob_id, runoob_title,
runoob_author, submission_date
FROM runoob_tbl';
mysqli_select_db( $conn, 'RUNOOB' );
$retval = mysqli_query( $conn, $sql );
if(! $retval )
{
die('無法讀取資料: ' . mysqli_error($conn));
}
echo '<h2>菜鳥教程 mysqli_fetch_assoc 測試<h2>';
echo '<table border="1"><tr><td>教程 ID</td><td>標題</td><td>作者</td><td>提交日期</td></tr>';
while($row = mysqli_fetch_assoc($retval))
{
echo "<tr><td> {$row['runoob_id']}</td> ".
"<td>{$row['runoob_title']} </td> ".
"<td>{$row['runoob_author']} </td> ".
"<td>{$row['submission_date']} </td> ".
"</tr>";
}
echo '</table>';
mysqli_close($conn);
?>

你也可以使用常量 MYSQLI_NUM 作為 PHP mysqli_fetch_array()
函式的第二個引數,返回數字陣列。
例項
以下例項使用 MYSQLI_NUM 引數顯示資料表 runoob_tbl 的所有記錄:
<?php
$dbhost = 'localhost:3306'; // mysql伺服器主機地址
$dbuser = 'root'; // mysql使用者名稱
$dbpass = '123456'; // mysql使用者名稱密碼
$conn = mysqli_connect($dbhost, $dbuser, $dbpass);
if(! $conn )
{
die('連線失敗: ' . mysqli_error($conn));
}
// 設定編碼,防止中文亂碼
mysqli_query($conn , "set names utf8");
$sql = 'SELECT runoob_id, runoob_title,
runoob_author, submission_date
FROM runoob_tbl';
mysqli_select_db( $conn, 'RUNOOB' );
$retval = mysqli_query( $conn, $sql );
if(! $retval )
{
die('無法讀取資料: ' . mysqli_error($conn));
}
echo '<h2>菜鳥教程 mysqli_fetch_array 測試<h2>';
echo '<table border="1"><tr><td>教程 ID</td><td>標題</td><td>作者</td><td>提交日期</td></tr>';
while($row = mysqli_fetch_array($retval, MYSQLI_NUM))
{
echo "<tr><td> {$row[0]}</td> ".
"<td>{$row[1]} </td> ".
"<td>{$row[2]} </td> ".
"<td>{$row[3]} </td> ".
"</tr>";
}
echo '</table>';
mysqli_close($conn);
?>

記憶體釋放
在我們執行完 SELECT 語句後,釋放遊標記憶體是一個很好的習慣。
可以通過 PHP 函式 mysqli_free_result() 來實現記憶體的釋放。
以下例項演示了該函式的使用方法。
例項
使用 mysqli_free_result 釋放記憶體:
<?php
$dbhost = 'localhost:3306'; // mysql伺服器主機地址
$dbuser = 'root'; // mysql使用者名稱
$dbpass = '123456'; // mysql使用者名稱密碼
$conn = mysqli_connect($dbhost, $dbuser, $dbpass);
if(! $conn )
{
die('連線失敗: ' . mysqli_error($conn));
}
// 設定編碼,防止中文亂碼
mysqli_query($conn , "set names utf8");

$sql = 'SELECT runoob_id, runoob_title,
runoob_author, submission_date
FROM runoob_tbl';
mysqli_select_db( $conn, 'RUNOOB' );
$retval = mysqli_query( $conn, $sql );
if(! $retval )
{
die('無法讀取資料: ' . mysqli_error($conn));
}
echo '<h2>菜鳥教程 mysqli_fetch_array 測試<h2>';
echo '<table border="1"><tr><td>教程 ID</td><td>標題</td><td>作者</td><td>提交日期</td></tr>';
while($row = mysqli_fetch_array($retval, MYSQLI_NUM))
{
echo "<tr><td> {$row[0]}</td> ".
"<td>{$row[1]} </td> ".
"<td>{$row[2]} </td> ".
"<td>{$row[3]} </td> ".
"</tr>";
}
echo '</table>';
// 釋放記憶體
mysqli_free_result($retval);
mysqli_close($conn);
?>

select _column,_column from _table [where Clause] [limit N][offset M]
select * : 返回所有記錄
limit N : 返回 N 條記錄
offset M : 跳過 M 條記錄, 預設 M=0, 單獨使用似乎不起作用
limit N,M : 相當於 offset N limit M , 從第 N 條記錄開始, 返回 M 條記錄
實現分頁:
select * from _table limit (page_number-1)*lines_perpage, lines_perpage

select * from _table limit lines_perpage offset (page_number-1)*lines_perpage

MySQL limit 應用的一些例子。
語法格式:
SELECT * FROM table LIMIT [offset,] rows | rows OFFSET offset
解析:LIMIT 子句可以被用於強制 SELECT 語句返回指定的記錄數。
LIMIT 接受一個或兩個數字引數。引數必須是一個整數常量。
如果給定兩個引數,第一個引數指定第一個返回記錄行的偏移量,
第二個引數指定返回記錄行的最大數目。
初始記錄行的偏移量是 0(而不是 1): 為了與 PostgreSQL 相容,
MySQL 也支援句法: LIMIT # OFFSET #。

mysql> SELECT * FROM table LIMIT 5,10; // 檢索記錄行 6-15

//為了檢索從某一個偏移量到記錄集的結束所有的記錄行,可以指定第二個引數為 -1:
mysql> SELECT * FROM table LIMIT 95,-1; // 檢索記錄行 96-last.

//如果只給定一個引數,它表示返回最大的記錄行數目:
mysql> SELECT * FROM table LIMIT 5; //檢索前 5 個記錄行

//換句話說,LIMIT n 等價於 LIMIT 0,n。
Mysql 的分頁查詢語句的效能分析
MySql 分頁 sql 語句,如果和 MSSQL 的 TOP 語法相比,
那麼 MySQL 的 LIMIT 語法要顯得優雅了許多。使用它來分頁是再自然不過的事情了。

2.1 最基本的分頁方式:
SELECT ... FROM ... WHERE ... ORDER BY ... LIMIT ...
在中小資料量的情況下,這樣的 SQL 足夠用了,唯一需要注意的問題就是確保使用了索引。

舉例來說,如果實際 SQL 類似下面語句,那麼在 category_id, id 兩列上建立複合索引比較好。

SELECT * FROM articles WHERE category_id = 123 ORDER BY id LIMIT 50, 10

2.2 子查詢的分頁方式
隨著資料量的增加,頁數會越來越多,檢視後幾頁的 SQL 就可能類似:

SELECT * FROM articles WHERE category_id = 123 ORDER BY id LIMIT 10000, 10
一言以蔽之,就是越往後分頁,LIMIT 語句的偏移量就會越大,速度也會明顯變慢。

此時,我們可以通過子查詢的方式來提高分頁效率,大致如下:

SELECT * FROM articles WHERE id >=
(SELECT id FROM articles WHERE category_id = 123 ORDER BY id LIMIT 10000, 1) LIMIT 10

2.3 JOIN 分頁方式
SELECT * FROM `content` AS t1
JOIN (SELECT id FROM `content` ORDER BY id desc LIMIT ".($page-1)*$pagesize.", 1) AS t2
WHERE t1.id <= t2.id ORDER BY t1.id desc LIMIT $pagesize;
經過我的測試,join 分頁和子查詢分頁的效率基本在一個等級上,消耗的時間也基本一致。

Mysql 簡單查詢語句,可以通過不同的查詢語句進行套用。
/*websites 表名 NAME alexa url country 欄位*/
SELECT * FROM websites; /* 查詢表所有資料 */

SELECT NAME FROM websites; /* 查詢表字段資料 */

SELECT * FROM websites where name = "廣西"; /* 查詢表字段下條件資料 */

SELECT * from websites where name like "_o%"; /* 模糊查詢表下資料 */

SELECT * FROM websites where id BETWEEN "1" AND "5"; /* 查詢表下欄位範圍資料 */

SELECT * FROM websites WHERE name in ("廣西","百度"); /* 查詢表字段下固定條件資料 */

SELECT DISTINCT country FROM Websites; /* 查詢去重值 */

SELECT * FROM Websites WHERE country = "CN" AND alexa > 50; /*查詢表下範圍條件資料*/

SELECT * FROM Websites WHERE country = "USA" OR country="sh"; /* 查詢表下條件不同值 */

SELECT * FROM Websites ORDER BY alexa; /* 查詢表下值排序結果 */

SELECT * FROM Websites ORDER BY alexa DESC; /* 查詢表下排序結果降序 */

SELECT * FROM Websites LIMIT 2; /* 查詢表下範圍資料 */

SELECT name as zzz from websites; /*別名查詢表下資料*/