PHPプログラミング

最終更新日:
公開日:

レシピ

データベース MySQL / MariaDB

mysqliのSELECT文を使った様々なデータの取得方法

MySQLiクラスのオブジェクトとSQLのSELECT文を使って、様々な条件で必要なデータを検索して取得する方法について解説します。

この記事のポイント

  • SQLで取得するデータの条件はWHERE句で指定する
  • ORDER BY句で取得するデータの並びを指定する
  • 取得するデータの上限数をLIMIT句で指定する

目次

必要なデータを、必要な順に、必要な数だけ取得する

SQLのデータを取得するSELECT文は条件の書き方次第で、必要なデータに絞った検索やデータの取得が可能です。

今回は次のようなuserテーブルにデータが入っていることを想定して、様々な条件を指定したデータの取得を解説していきます。

テーブル名:user
idnamegenderagemodify_datetimecreate_datetime
1青山 太郎1352016-10-04 00:00:002014-04-10 00:00:00
2飯島 彩子2262016-10-02 00:00:002014-04-10 00:00:00
3宇多 太郎1272016-10-01 00:00:002014-04-10 00:00:00
4江藤 彩子2322016-09-20 00:00:002015-08-07 00:00:00
5大島 太郎1222016-09-03 00:00:002012-10-05 00:00:00
6加藤 彩子2412016-09-18 00:00:002012-04-20 00:00:00
7岸田 太郎1272016-09-18 00:00:002012-04-20 00:00:00
8工藤 彩子2392016-10-01 00:00:002012-05-10 00:00:00
9小島 太郎1302016-09-10 00:00:002012-04-20 00:00:00
10佐藤 彩子2322016-09-24 00:00:002012-05-15 00:00:00

各カラムの役割は次の通りです。

  • id – ID(主キー)
  • name – 名前
  • gender – 性別。1は男性、2は女性
  • age – 年齢
  • modify_datetime – データ更新日時
  • create_datetime – データ登録日時

MySQLiクラスについては「オブジェクト」と「手続き型(関数)」の2通りの書き方がありますが、今回は主に「オブジェクト」を使って進めていきます。
「手続き型(関数)」を使う倍においても全く同じSQLを実行できるので、置き換えて読んでいただくことも可能です。
MySQLiクラスSELECT文の最も基本的な扱い方については、「mysqliでMySQL/MariaDBからデータを取得:SELECT」を参照してください。

条件を満たすデータを抽出して取得する

WHERE句に指定した値と等しいデータのみ取得します。
以下の例はidカラムが「8」のデータを取得します。
赤字の箇所は検索したいIDをセットするポイントになるコードです。

index.php

// (1)検索するデータのID
$id = 8;

// (2)データベースと接続
$mysqli = new mysqli( 'host_name', 'user_name', 'password', 'database_name');

if( $mysqli->connect_errno ) {
	echo $mysqli->connect_errno . ' : ' . $mysqli->connect_error;
}

// (3)文字コードを設定
$mysqli->set_charset('utf8');

// (4)プリペアドステートメントを使ってデータを取得
$stmt = $mysqli->prepare('SELECT * FROM user WHERE id = ?');

// (5)検索するIDをセット
$stmt->bind_param( 'i', $id);

// (6)検索を実行
$stmt->execute();

// (7)結果を取得
$result = $stmt->get_result();

// (8)結果を出力
while( $row_data = $result->fetch_array(MYSQLI_ASSOC) ) {
	var_dump($row_data);
}

// (9)データベースとの接続解除
$mysqli->close();

実行結果

array(6) {
	["id"]=> int(8)
	["name"]=> string(13) "工藤 彩子"
	["gender"]=> int(2)
	["age"]=> int(39)
	["modify_datetime"]=> string(19) "2016-10-01 00:00:00"
	["create_datetime"]=> string(19) "2012-05-10 00:00:00"
}

(4)のSQLを書く箇所で、データを絞り込む条件はWHERE句の後ろに書きます。
prepareメソッドにSQLを渡してプリペアドステートメントを実行する準備をしますが、この時点では検索するデータのIDは指定せず、プレースホルダーの「?」を記述します。
このプレースホルダーは続く(5)でbind_paramメソッドを使って値をセットします。

bind_paramメソッドのパラメーター(引数)には(1)で用意した変数の前に「i」という文字があります。
これは先ほどのプレースホルダー「?」を変数の値に置き換えるときのデータの型を指定するものです。
i」はinteger(整数)の頭文字です。

今回はプレースホルダーが1つだけなので、「$id -> i」と対応させており、最終的には変数の値「8」が「?」に置き換わります。

指定した範囲の値を持つデータを抽出して取得する

ある特定の範囲の値を持ったデータに絞り込んで取得したい場合は、WHERE句BETWEENで値の範囲を指定します。

index.php

// (1)検索するデータの年齢
$min_age = 25;
$max_age = 27;

// (2)データベースと接続
$mysqli = new mysqli( 'host_name', 'user_name', 'password', 'database_name');

if( $mysqli->connect_errno ) {
	echo $mysqli->connect_errno . ' : ' . $mysqli->connect_error;
}

// (3)文字コードを設定
$mysqli->set_charset('utf8');

// (4)プリペアドステートメントを使ってデータを取得
$stmt = $mysqli->prepare('SELECT * FROM user WHERE age BETWEEN ? AND ?');

// (5)検索するIDをセット
$stmt->bind_param( 'ii', $min_age, $max_age);

// (6)検索を実行
$stmt->execute();

// (7)結果を取得
$result = $stmt->get_result();

// (8)結果を出力
while( $row_data = $result->fetch_array(MYSQLI_ASSOC) ) {
	var_dump($row_data);
}

// (9)データベースとの接続解除
$mysqli->close();

実行結果

array(6) {
	["id"]=> int(2)
	["name"]=> string(13) "飯島 彩子"
	["gender"]=> int(2)
	["age"]=> int(26)
	["modify_datetime"]=> string(19) "2016-10-02 00:00:00"
	["create_datetime"]=> string(19) "2014-04-10 00:00:00"
}
array(6) {
	["id"]=> int(3)
	["name"]=> string(13) "宇多 太郎"
	["gender"]=> int(1)
	["age"]=> int(27)
	["modify_datetime"]=> string(19) "2016-10-01 00:00:00"
	["create_datetime"]=> string(19) "2014-04-10 00:00:00"
}
array(6) {
	["id"]=> int(7)
	["name"]=> string(13) "岸田 太郎"
	["gender"]=> int(1)
	["age"]=> int(27)
	["modify_datetime"]=> string(19) "2016-09-18 00:00:00"
	["create_datetime"]=> string(19) "2012-04-20 00:00:00"
}

今回は年齢が数値で入っているageカラムに25〜27が入っているデータを検索して取得する条件式になっています。
「カラム名 BETWEEN 値1 AND 値2」とすることで、「値1以上〜値2以下」の間で絞り込むことができます。

(5)でbind_paramメソッドを使ってプレースホルダーに値をセットするときに、今回はプレースホルダーが2つなので1つ目のぱあらメータが「ii」と2つ並びます。
先頭から順に「$min_age -> i」、「$max_age -> i」と対応し、値が入ると「BETWEEN 25 AND 27」となります。

取得するデータを日付で絞り込む

特定期間の日付で検索してデータを取得したい場合は、WHERE句の条件式に「開始の日付 <= カラム名」と「カラム名 <= 終了の日付」の2つの条件式を「AND」で繋いで指定します。

以下の例では登録日時が入ったcreate_datetimeカラムに対して、2014年04月01日から30日までの日付に絞ってデータを取得します。

index.php

// (1)検索するデータの日付
$start_date = "2014-04-01";
$end_date = "2014-04-30";

// (2)データベースと接続
$mysqli = new mysqli( 'host_name', 'user_name', 'password', 'database_name');

if( $mysqli->connect_errno ) {
	echo $mysqli->connect_errno . ' : ' . $mysqli->connect_error;
}

// (3)文字コードを設定
$mysqli->set_charset('utf8');

// (4)プリペアドステートメントを使ってデータを取得
$stmt = $mysqli->prepare('SELECT * FROM user WHERE ? <= create_datetime AND create_datetime <= ?');

// (5)検索するIDをセット
$stmt->bind_param( 'ss', $start_date, $end_date);

// (6)検索を実行
$stmt->execute();

// (7)結果を取得
$result = $stmt->get_result();

// (8)結果を出力
while( $row_data = $result->fetch_array(MYSQLI_ASSOC) ) {
	var_dump($row_data);
}

// (9)データベースとの接続解除
$mysqli->close();

実行結果

array(6) {
	["id"]=> int(1)
	["name"]=> string(13) "青山 太郎"
	["gender"]=> int(1)
	["age"]=> int(35)
	["modify_datetime"]=> string(19) "2016-10-04 00:00:00"
	["create_datetime"]=> string(19) "2014-04-10 00:00:00"
}
array(6) {
	["id"]=> int(2)
	["name"]=> string(13) "飯島 彩子"
	["gender"]=> int(2)
	["age"]=> int(26)
	["modify_datetime"]=> string(19) "2016-10-02 00:00:00"
	["create_datetime"]=> string(19) "2014-04-10 00:00:00"
}
array(6) {
	["id"]=> int(3)
	["name"]=> string(13) "宇多 太郎"
	["gender"]=> int(1)
	["age"]=> int(27)
	["modify_datetime"]=> string(19) "2016-10-01 00:00:00"
	["create_datetime"]=> string(19) "2014-04-10 00:00:00"
}

WHERE句は「AND」の他に、「OR」を使って「または」の条件式を指定することも可能です。
例えば、「年齢が24未満、または40以上」で検索したい場合は「age < 24 OR 40 <= age」のようになります。

今回はプレースホルダーに渡す値が日付形式の文字列になるため、bind_paramメソッドの1つ目のパラメータはstring(文字列)の「s」を2つ並びます。
プレースホルダーは先頭から「$start_date -> s」、「$end_date -> s」と置き換わり、「“2014-04-01” <= create_datetime AND create_datetime <= “2014-04-30”」となります。

取得するデータの並び順を指定する

取得したデータの並び順を指定するときは「ORDER BY句」で指定します。
例えば「年齢の低い順」や「最近更新された順」など、一定の順番で並んだ状態でデータを取得することができます。

以下の例は2016年10月1日以降に更新されたデータ(modify_datetimeカラム)から、年齢の低い順(ageカラムの値が小さい順)にデータを取得します。

index.php

// (1)検索するデータの日付
$start_date = "2016-10-01";

// (2)データベースと接続
$mysqli = new mysqli( 'host_name', 'user_name', 'password', 'database_name');

if( $mysqli->connect_errno ) {
	echo $mysqli->connect_errno . ' : ' . $mysqli->connect_error;
}

// (3)文字コードを設定
$mysqli->set_charset('utf8');

// (4)プリペアドステートメントを使ってデータを取得
$stmt = $mysqli->prepare('SELECT * FROM user WHERE ? <= modify_datetime ORDER BY age ASC');

// (5)検索するIDをセット
$stmt->bind_param( 's', $start_date);

// (6)検索を実行
$stmt->execute();

// (7)結果を取得
$result = $stmt->get_result();

// (8)結果を出力
while( $row_data = $result->fetch_array(MYSQLI_ASSOC) ) {
	var_dump($row_data);
}

// (9)データベースとの接続解除
$mysqli->close();

実行結果

array(6) {
	["id"]=> int(2)
	["name"]=> string(13) "飯島 彩子"
	["gender"]=> int(2)
	["age"]=> int(26)
	["modify_datetime"]=> string(19) "2016-10-02 00:00:00"
	["create_datetime"]=> string(19) "2014-04-10 00:00:00"
}
array(6) {
	["id"]=> int(3)
	["name"]=> string(13) "宇多 太郎"
	["gender"]=> int(1)
	["age"]=> int(27)
	["modify_datetime"]=> string(19) "2016-10-01 00:00:00"
	["create_datetime"]=> string(19) "2014-04-10 00:00:00"
}
array(6) {
	["id"]=> int(1)
	["name"]=> string(13) "青山 太郎"
	["gender"]=> int(1)
	["age"]=> int(35)
	["modify_datetime"]=> string(19) "2016-10-04 00:00:00"
	["create_datetime"]=> string(19) "2014-04-10 00:00:00"
}
array(6) {
	["id"]=> int(8)
	["name"]=> string(13) "工藤 彩子"
	["gender"]=> int(2)
	["age"]=> int(39)
	["modify_datetime"]=> string(19) "2016-10-01 00:00:00"
	["create_datetime"]=> string(19) "2012-05-10 00:00:00"
}

並び順の指定は昇順はASC、降順はDESCと指定します。
ORDER BY句ASCDESCのどちらも指定がないときはASCの指定になるため、上記のSQLのように昇順にするときは「ORDER BY age ASC」を「ORDER BY age」と省略して書くことも可能です。

取得するデータの上限数を指定する

LIMIT句を使って取得するデータの上限数を指定することができます。

以下の例は2016年10月1日以降に更新されたデータ(modify_datetimeカラム)から、年齢の高い順(ageカラムの値が大きい順)に最大2件のデータを取得します。

index.php

// (1)検索するデータの日付
$start_date = "2016-10-01";

// (2)データベースと接続
$mysqli = new mysqli( 'host_name', 'user_name', 'password', 'database_name');

if( $mysqli->connect_errno ) {
	echo $mysqli->connect_errno . ' : ' . $mysqli->connect_error;
}

// (3)文字コードを設定
$mysqli->set_charset('utf8');

// (4)プリペアドステートメントを使ってデータを取得
$stmt = $mysqli->prepare('SELECT * FROM user WHERE ? <= modify_datetime ORDER BY age DESC LIMIT 2');

// (5)検索するIDをセット
$stmt->bind_param( 's', $start_date);

// (6)検索を実行
$stmt->execute();

// (7)結果を取得
$result = $stmt->get_result();

// (8)結果を出力
while( $row_data = $result->fetch_array(MYSQLI_ASSOC) ) {
	var_dump($row_data);
}

// (9)データベースとの接続解除
$mysqli->close();

実行結果

array(6) {
	["id"]=> int(8)
	["name"]=> string(13) "工藤 彩子"
	["gender"]=> int(2)
	["age"]=> int(39)
	["modify_datetime"]=> string(19) "2016-10-01 00:00:00"
	["create_datetime"]=> string(19) "2012-05-10 00:00:00"
}
array(6) {
	["id"]=> int(1)
	["name"]=> string(13) "青山 太郎"
	["gender"]=> int(1)
	["age"]=> int(35)
	["modify_datetime"]=> string(19) "2016-10-04 00:00:00"
	["create_datetime"]=> string(19) "2014-04-10 00:00:00"
}

今回はLIMIT句で取得するデータの上限数を2件に指定していますが、10件取得したい場合は「LIMIT 10」、1000件の場合は「LIMIT 1000」と指定します。

こちらの記事は役に立ちましたか?

ありがとうございます。
もしよろしければ、あわせてフィードバックや要望などをご入力ください。

コメントありがとうございます!
運営の参考にさせていただきます。