Help us understand the problem. What is going on with this article?

PDOフェッチパターン大全

More than 3 years have passed since last update.

忙しい人向け

Q. PDO::FETCH_ASSOCでフェッチするとき,キーを整数連番じゃなくてidにする方法は?

A. PDO::FETCH_UNIQUEを組み合わせる.

$sql = "SELECT id, * FROM people WHERE gender = 'female'";
$rows = $pdo->query($sql)->fetchAll(PDO::FETCH_ASSOC|PDO::FETCH_UNIQUE);
var_dump($rows);
/*
[
    3 => ['id' => '3', 'name' => 'Lucy', 'gender' => 'female'],
    5 => ['id' => '5', 'name' => 'Mary', 'gender' => 'female'],
]
*/
MySQLではシンタックスエラー回避のためにテーブル名を明示してください
$sql = "SELECT id, people.* FROM people WHERE gender = 'female'";

はじめに

PDOStatement::fetchAllの活用法を紹介します.ここでは,以下のものに限定します.

  • 結果セットがスカラー値配列のみで構成される
  • ある程度役に立ちそうなもの

PDO::FETCH_OBJおよびPDO::FETCH_CLASS系に関しては@Hirakuさんや@k-holyさんの記事を参照してください.

なお,テーブルは以下のようなものを考え,これをpeopleテーブルとします.

id name gender
1 Bob male
2 Bill male
3 Lucy female
4 Mike male
5 Mary female
作成用コード
$pdo = new PDO('sqlite::memory:', '', '', [
    PDO::ATTR_ERRMODE => PDO::ERRMODE_EXCEPTION,
]);
$pdo->exec("
    CREATE TABLE people(id INTEGER PRIMARY KEY, name TEXT, gender TEXT);
    INSERT INTO people
        SELECT 1, 'Bob', 'male' UNION ALL
        SELECT 2, 'Bill', 'male' UNION ALL
        SELECT 3, 'Lucy', 'female' UNION ALL
        SELECT 4, 'Mike', 'male' UNION ALL
        SELECT 5, 'Mary', 'female'
    ;
");

パターン一覧

スカラー値として取得

集約関数の適用結果を整数で取得

スッキリ感: ★★☆

$sql = "SELECT COUNT(*) FROM people WHERE gender = 'female'";
$count = (int)$pdo->query($sql)->fetchColumn();
var_dump($count); // 2
  • 値として使うカラム番号のデフォルトは0ですが,第1引数で変更できます.

1次元配列として取得

1件しか存在し得ないカラム群を取得

スッキリ感: ★☆☆

$sql = "SELECT * FROM people WHERE id = 2";
$row = $pdo->query($sql)->fetch(PDO::FETCH_ASSOC);
if ($row === false) {
    throw new \RuntimeException('Not Found'); // falseになることを考慮したコードを書くべき
}
var_dump($row);
/*
['id' => '2', 'name' => 'Bill', 'gender' => 'male']
*/

親 の 顔 よ り 見 た 光 景

整数連番をキー,1カラムを値とする配列を取得

スッキリ感: ★★☆

$sql = "SELECT name FROM people WHERE gender = 'female'";
$names = $pdo->query($sql)->fetchAll(PDO::FETCH_COLUMN);
var_dump($names); // ['Lucy', 'Mary']
  • 値として使うカラム番号のデフォルトは0ですが,第2引数で変更できます.

先頭カラムをキー,別の1カラムを値とする配列を取得

スッキリ感: ★★★

正確に2カラムのみ選択しておく必要あり
$sql = "SELECT id, name FROM people WHERE gender = 'female'";
$names = $pdo->query($sql)->fetchAll(PDO::FETCH_KEY_PAIR);
var_dump($names); // [3 => 'Lucy', 5 => 'Mary']
3カラム目以降を捨てたい,あるいは値として使うカラム番号を指定したい
$sql = "SELECT * FROM people WHERE gender = 'female'";
$names = $pdo->query($sql)->fetchAll(PDO::FETCH_COLUMN|PDO::FETCH_UNIQUE);
var_dump($names); // [3 => 'Lucy', 5 => 'Mary']

ほとんどの場合PDO::FETCH_KEY_PAIRで事足りますが,PDO::FETCH_UNIQUEのこんな使い方知っている人,少ないんじゃないでしょうか.

  • 値として使うカラム番号のデフォルトは1ですが,第2引数で変更できます.
  • キーとして使うカラム番号は指定できず,常に0となります.
  • もしキーが重複している場合,最後に見つかった値が優先されます.

2次元配列として取得

整数連番をキー,カラム群を値とする配列を取得

スッキリ感: ★☆☆

$sql = "SELECT * FROM people WHERE gender = 'female'";
$rows = $pdo->query($sql)->fetchAll(PDO::FETCH_ASSOC);
var_dump($rows);
/*
[
    ['id' => '3', 'name' => 'Lucy', 'gender' => 'female'],
    ['id' => '5', 'name' => 'Mary', 'gender' => 'female'],
]
*/

実 家 の よ う な 安 心 感

先頭カラムをキー,カラム群を値とする配列を取得

スッキリ感: ★★★

キー自身はカラム群から除外
$sql = "SELECT * FROM people WHERE gender = 'female'";
$rows = $pdo->query($sql)->fetchAll(PDO::FETCH_ASSOC|PDO::FETCH_UNIQUE);
var_dump($rows);
/*
[
    3 => ['name' => 'Lucy', 'gender' => 'female'],
    5 => ['name' => 'Mary', 'gender' => 'female'],
]
*/
キー自身もカラム群に含む
$sql = "SELECT id, * FROM people WHERE gender = 'female'";
$rows = $pdo->query($sql)->fetchAll(PDO::FETCH_ASSOC|PDO::FETCH_UNIQUE);
var_dump($rows);
/*
[
    3 => ['id' => '3', 'name' => 'Lucy', 'gender' => 'female'],
    5 => ['id' => '5', 'name' => 'Mary', 'gender' => 'female'],
]
*/
MySQLではシンタックスエラー回避のためにテーブル名を明示してください
$sql = "SELECT id, people.* FROM people WHERE gender = 'female'";

これをやりたかった人114514364364人ぐらいいそう(名推理)

  • キーとして使うカラム番号は指定できず,常に0となります.
  • もしキーが重複している場合,最後に見つかった値が優先されます.

先頭カラムをキー,別の1カラムのキー毎のグループを値とする配列を取得

スッキリ感: ★★★

$sql = "SELECT gender, name FROM people";
$grouped_names = $pdo->query($sql)->fetchAll(PDO::FETCH_COLUMN|PDO::FETCH_GROUP);
var_dump($grouped_names); 
/*
[
    'male' => ['Bob', 'Bill', 'Mike'],
    'female' => ['Lucy', 'Mary'],
]
*/
  • グループ内の値として使うカラム番号のデフォルトは1ですが,第1引数で変更できます.
  • キーとして使うカラム番号は指定できず,常に0となります.

3次元配列として取得

先頭カラムをキー,カラム群のキー毎のグループを値とする配列を取得

スッキリ感: ★★★

キー自身はカラム群から除外
$sql = "SELECT gender, id, name FROM people";
$grouped_rows = $pdo->query($sql)->fetchAll(PDO::FETCH_ASSOC|PDO::FETCH_GROUP);
var_dump($grouped_rows); 
/*
[
    'male' => [
        ['id' => '1', 'name' => 'Bob'],
        ['id' => '2', 'name' => 'Bill'],
        ['id' => '4', 'name' => 'Mike'],
    ],
    'female' => [
        ['id' => '3', 'name' => 'Lucy'],
        ['id' => '5', 'name' => 'Mary'],
    ],
]
*/
キー自身もカラム群に含む
$sql = "SELECT gender, * FROM people";
$grouped_rows = $pdo->query($sql)->fetchAll(PDO::FETCH_ASSOC|PDO::FETCH_GROUP);
var_dump($grouped_rows); 
/*
[
    'male' => [
        ['id' => '1', 'name' => 'Bob', 'gender' => 'male'],
        ['id' => '2', 'name' => 'Bill', 'gender' => 'male'],
        ['id' => '4', 'name' => 'Mike', 'gender' => 'male'],
    ],
    'female' => [
        ['id' => '3', 'name' => 'Lucy', 'gender' => 'female'],
        ['id' => '5', 'name' => 'Mary', 'gender' => 'female'],
    ],
]
*/
MySQLではシンタックスエラー回避のためにテーブル名を明示してください
$sql = "SELECT gender, people.* FROM people";
  • キーとして使うカラム番号は指定できず,常に0となります.
mpyw
PHP(Laravel) / JavaScript(React/Redux/ReactNative/Vue) / MySQL あたりが得意分野なWeb系エンジニア。最近マンネリ化がひどいので Go / Kotlin / Rust / Swift あたりから何か掘り下げたいと思っている。Go は 2.x 出てから書きます。古い記事はそのまま参考にしないようにご注意ください
http://gravatar.com/mpyw
synapse
Synapseは、オンラインサロンサービスにおけるパイオニアとして、かつて存在していたスタートアップです。
https://synapseam.github.io/
Why not register and get more from Qiita?
  1. We will deliver articles that match you
    By following users and tags, you can catch up information on technical fields that you are interested in as a whole
  2. you can read useful information later efficiently
    By "stocking" the articles you like, you can search right away
Comments
No comments
Sign up for free and join this conversation.
If you already have a Qiita account
Why do not you register as a user and use Qiita more conveniently?
You need to log in to use this function. Qiita can be used more conveniently after logging in.
You seem to be reading articles frequently this month. Qiita can be used more conveniently after logging in.
  1. We will deliver articles that match you
    By following users and tags, you can catch up information on technical fields that you are interested in as a whole
  2. you can read useful information later efficiently
    By "stocking" the articles you like, you can search right away
ユーザーは見つかりませんでした