採点されません。匿名です。 間違えることは学習の一部です。読むだけでもかまいません。

SELECT で行を取り出す

テクノロジ系 / db (PDO / SQL / マルチDB)

SELECT で行を取り出す

Lesson 11 / Chapter 3

SELECT は「テーブルから行を取り出す」命令

SELECT id, name FROM users ORDER BY id;
  • SELECT 列名取り出したい列 を指定
  • FROM テーブル名どのテーブルから
  • ORDER BY 列名並び順 を固定 (順序を保証したいときは必ず付ける)
  • * を書くと全列 (SELECT * FROM users)

PHP からは $pdo->query() で実行

<?php
$pdo = new PDO('sqlite:' . getenv('DOJO_DB_PATH'));
$pdo->setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION);

$stmt = $pdo->query('SELECT id, name FROM users ORDER BY id');
  • $pdo->query($sql) に SQL 文字列を渡すと、結果が PDOStatement で返る
  • query()値を埋め込まない固定 SQL 専用。ユーザー入力を混ぜるときは prepare (ch04)

foreach で 1 行ずつ取り出す

foreach ($pdo->query('SELECT id, name FROM users ORDER BY id') as $row) {
    echo $row['id'] . ': ' . $row['name'] . "\n";
}

実行結果:

1: 太郎
2: 花子
3: 次郎
  • 1 行が連想配列で渡ってくる: $row['id'] / $row['name']
  • 行数が多くても メモリに全部載せずに済む (1 行ずつ処理)

fetchAll() で全行を 1 つの配列に

$stmt = $pdo->query('SELECT id, name FROM users ORDER BY id');
$rows = $stmt->fetchAll(PDO::FETCH_ASSOC);

// $rows は配列の配列
// [
//   ['id' => 1, 'name' => '太郎'],
//   ['id' => 2, 'name' => '花子'],
//   ['id' => 3, 'name' => '次郎'],
// ]

foreach ($rows as $row) {
    echo $row['name'] . "\n";
}
  • 後から件数を数えたい (count($rows)) / 並べ替えたいときは fetchAll の方が楽
  • ただし 全行メモリに載る ので、大量データなら foreach で 1 行ずつの方が安全

COUNT(*) で件数だけ取る

$stmt = $pdo->query('SELECT COUNT(*) AS cnt FROM users');
$row = $stmt->fetch(PDO::FETCH_ASSOC);
echo $row['cnt'] . "\n";   // 3
  • 1 行 1 列だけ返ってくるパターン
  • fetch() は 1 行だけ取り出すメソッド
  • AS cnt で列に名前を付けると $row['cnt'] で取れて読みやすい

このチャプターでできるようになること

SELECT 列 FROM テーブル ORDER BY 列 を書ける

$pdo->query() で SELECT を実行できる

foreach で 1 行ずつ処理できる

fetchAll(PDO::FETCH_ASSOC) で全行を配列にできる

✅ 行は連想配列 ($row['列名']) でアクセスする

→ ドリルへ

考えてみよう

既定では正解・不正解の判定はしません。自分のペースで「答えを見る」を。採点してほしい場合だけ「採点してほしい」を押してください。

ドリル 01 — 全件 SELECT して "id: name" 形式で出力

問題

users テーブル (id, name, age) には次の 3 行が入っています。

idnameage
1太郎20
2花子25
3次郎30

id の昇順で全件 SELECT し、各行を id: name の形式 (id と name を : で連結) でちょうど 3 行出力してください。

期待される出力:

1: 太郎
2: 花子
3: 次郎

採点

php scripts/grade.php topics/db/ch03-select-basic/drill/01-select-all/

ヒント

  • SELECT id, name FROM users ORDER BY id
  • foreach ($pdo->query($sql) as $row) { ... }
  • 出力は echo $row['id'] . ': ' . $row['name'] . "\n";

ドリル 02 — 件数を出力

問題

users テーブルの行数を SELECT COUNT(*) で取得し、その数字をちょうど 1 行で出力してください。

users には 3 行入っています (前の drill と同じデータ)。

期待される出力:

3

採点

php scripts/grade.php topics/db/ch03-select-basic/drill/02-count-rows/

ヒント

  • SELECT COUNT(*) AS cnt FROM users
  • 1 行 1 列だけ返るので $stmt->fetch(PDO::FETCH_ASSOC) で 1 行だけ取り出す
  • echo $row['cnt'] . "\n";

ドリル 03 — name 列だけを取り出して改行区切りで出力

問題

users テーブルから name 列だけを id 昇順で取得し、各名前を 1 行ずつ出力してください。

users には 3 行入っています (前の drill と同じデータ)。

期待される出力:

太郎
花子
次郎

採点

php scripts/grade.php topics/db/ch03-select-basic/drill/03-fetch-column/

ヒント

  • SELECT name FROM users ORDER BY id
  • foreach ($pdo->query($sql) as $row) { echo $row['name'] . "\n"; }
  • fetchAll を使って配列にして foreach でも OK