DISTINCT、GROUP BY、サブクエリ駆使!MySQLで列の重複を取り除くテクニック

2024-05-17

PHP、MySQL、SQL を使用して列から一意の値を選択する方法

このチュートリアルでは、PHP、MySQL、SQL を使用してデータベース表の列から一意の値を選択する方法を説明します。3 つの異なる方法を紹介します。

  1. DISTINCT キーワード
  2. GROUP BY 句
  3. 副問合せ

それぞれの方法について、具体的なコード例と実行結果を示します。

前提知識

このチュートリアルを理解するには、以下の知識が必要です。

  • PHP の基本的な構文
  • MySQL データベースの使用方法
  • SQLクエリの実行方法

使用するデータベース

このチュートリアルでは、次の構造を持つ users テーブルを使用します。

CREATE TABLE users (
  id INT PRIMARY KEY AUTO_INCREMENT,
  name VARCHAR(255) NOT NULL,
  email VARCHAR(255) NOT NULL,
  created_at DATETIME NOT NULL DEFAULT CURRENT_TIMESTAMP
);

このテーブルには、idnameemailcreated_at の 4 つの列があります。

DISTINCT キーワードは、SELECT クエリの結果から重複する値を削除するために使用されます。 以下は、name 列から一意の値を選択する例です。

<?php

$conn = new mysqli('localhost', 'username', 'password', 'database_name');

$sql = "SELECT DISTINCT name FROM users";
$result = $conn->query($sql);

if ($result->num_rows > 0) {
  while ($row = $result->fetch_assoc()) {
    echo $row['name'] . "<br>";
  }
} else {
  echo "一意の値が見つかりませんでした。";
}

$conn->close();

このコードを実行すると、次の出力が得られます。

Alice
Bob
Charlie

GROUP BY 句は、SELECT クエリの結果をグループ化するために使用されます。 各グループに対して、集計関数 (COUNT、SUM、AVG など) を適用することもできます。 以下は、name 列の値をグループ化し、各グループのレコード数をカウントする例です。

<?php

$conn = new mysqli('localhost', 'username', 'password', 'database_name');

$sql = "SELECT name, COUNT(*) AS count FROM users GROUP BY name";
$result = $conn->query($sql);

if ($result->num_rows > 0) {
  while ($row = $result->fetch_assoc()) {
    echo $row['name'] . ": " . $row['count'] . "<br>";
  }
} else {
  echo "一意の値が見つかりませんでした。";
}

$conn->close();
Alice: 1
Bob: 1
Charlie: 1

方法 3: 副問合せ

副問合せは、別のクエリの結果を返すクエリです。 以下は、name 列から一意の値を選択する副問合せを使用した例です。

<?php

$conn = new mysqli('localhost', 'username', 'password', 'database_name');

$sql = "SELECT name FROM users WHERE name IN (
  SELECT DISTINCT name FROM users
)";
$result = $conn->query($sql);

if ($result->num_rows > 0) {
  while ($row = $result->fetch_assoc()) {
    echo $row['name'] . "<br>";
  }
} else {
  echo "一意の値が見つかりませんでした。";
}

$conn->close();

このコードは、方法 1 と同じ結果を生成します。

このチュートリアルでは、PHP、MySQL、SQL を使用してデータベース表の列から一意の値を選択する方法を 3 通り紹介しました。 それぞれの方法には長所と短所があるので、状況に応じて適切な方法を選択してください。

補足

  • より複雑なクエリを作成するには、WHERE 句、ORDER BY 句、LIMIT 句などの他の SQL 句を組み合わせることができます。
  • PHP でデータベースを操作するには、MySQLi拡張モジュールを使用する必要があります。
  • MySQL データベースに接続するには、ホスト名、ユーザー名、パスワード、データベース名などの接続情報が必要です。

このチュートリアルが、PHP、MySQL、SQL を使用してデータベースからデータを操作




<?php

$conn = new mysqli('localhost', 'username', 'password', 'database_name');

$sql = "SELECT DISTINCT name FROM users";
$result = $conn->query($sql);

if ($result->num_rows > 0) {
  while ($row = $result->fetch_assoc()) {
    echo $row['name'] . "<br>";
  }
} else {
  echo "一意の値が見つかりませんでした。";
}

$conn->close();

このコードは以下の動作をします。

  1. mysqli 拡張機能を使用して、MySQL データベースへの接続を確立します。
  2. DISTINCT name FROM users という SQL クエリを実行します。 このクエリは、users テーブルの name 列から重複する値を削除して、一意の値のみを選択します。
  3. クエリの結果をフェッチし、各行をループ処理します。
  4. 各行の name カラムの値を出力します。
  5. データベース接続を閉じます。

実行方法

  1. 上記のコードをエディタに保存します。
  2. ファイルを .php 拡張子で保存します。
  3. Web サーバーでファイルをホストします。

出力

Alice
Bob
Charlie

説明

  • mysqli_connect() 関数は、MySQL データベースへの接続を確立します。 この関数は、ホスト名、ユーザー名、パスワード、データベース名を引数として取ります。
  • mysqli_query() 関数は、SQL クエリを実行します。 この関数は、SQL クエリ文字列を引数として取ります。
  • mysqli_fetch_assoc() 関数は、クエリの結果から連想配列を返します。 この配列には、各列名のキーと、その列の値が含まれています。
  • echo ステートメントは、文字列を出力します。
  • mysqli_close() 関数は、データベース接続を閉じます。

このコードはあくまで一例であり、状況に応じて変更する必要があります。 例えば、別のデータベースに接続したい場合は、接続情報を変更する必要があります。 また、別の列から一意の値を選択したい場合は、DISTINCT の後に列名を指定する必要があります。




以下のコードは、サブクエリを使用して一意の値を選択する方法を示しています。

SELECT name
FROM users
WHERE name NOT IN (
  SELECT name
  FROM users
  GROUP BY name
  HAVING COUNT(*) > 1
);

このクエリは、以下の手順で動作します。

  1. 内側のサブクエリは、name 列の値をグループ化し、各グループのレコード数をカウントします。
  2. 外側のクエリは、users テーブルから name 列の値を選択します。
  3. 外側のクエリは、WHERE 句を使用して、内側のサブクエリでカウント数が 1 を超えた name 値を除外します。

ウィンドウ関数

SELECT name
FROM users
ORDER BY name
ROW_NUMBER() OVER (PARTITION BY name ORDER BY name) AS row_num
HAVING row_num = 1;
  1. ORDER BY name 句を使用して、name 列の値を昇順にソートします。
  2. ROW_NUMBER() ウィンドウ関数は、各行に一意の行番号を割り当てます。
  3. PARTITION BY name 句を使用して、行番号を name 列の値ごとにグループ化します。
  4. HAVING 句を使用して、行番号が 1 の行のみを選択します。

仮想テーブル

CREATE TEMPORARY TABLE unique_names (
  name VARCHAR(255) NOT NULL
);

INSERT INTO unique_names (name)
SELECT DISTINCT name
FROM users;

SELECT name
FROM unique_names;
  1. unique_names という名前の仮想テーブルを作成します。
  2. DISTINCT キーワードを使用して、users テーブルから一意の name 値を unique_names テーブルに挿入します。

上記で紹介した方法は、それぞれ異なる長所と短所があります。 状況に応じて適切な方法を選択してください。

長所と短所

  • DISTINCT キーワード
    • 長所: 簡単で分かりやすい
    • 短所: 他の方法よりも時間がかかる場合がある
  • サブクエリ
    • 長所: 柔軟性が高い
  • ウィンドウ関数
    • 長所: 高速で効率的
    • 短所: MySQL 8 以降でのみ使用可能
  • 仮想テーブル
    • 長所: 読みやすくメンテナンスしやすい
    • 短所: 一時的なテーブルなので、クエリが終了すると削除される

php mysql sql


PHP date()関数を使ってMySQLのdatetime型カラムに日付を挿入する

MySQLのdatetime型は、以下のフォーマットで構成されます。YYYY-MM-DD HH:MM:SS年は4桁、月と日は2桁、時間は24時間表記、分と秒は2桁で表されます。それぞれの要素はハイフン(:)で区切られます。PHP date()フォーマット...


SQL EXISTS 構文 vs IN 構文 vs 相関サブクエリ:状況に合わせた使い分け

基本的な動作上記のように記述した場合、外部テーブルの各レコードに対して、内部テーブルで指定した条件に合致するレコードが存在するかどうかを調べます。EXISTS が TRUE を返す場合:外部テーブルのレコードと、内部テーブルで条件に合致するレコードが関連付けられていることを示します。...


【初心者向け】SQLiteデータベースでGROUP BYクエリを実行して集計結果を取得する方法

このチュートリアルでは、PHPを使用してSQLiteデータベースに対してGROUP BYクエリを実行し、各グループの行数を取得する方法を説明します。前提知識このチュートリアルを理解するには、以下の知識が必要です。PHPの基本的な構文SQLiteデータベースの操作方法...


MySQLにJDBC経由でUTF-8文字列を挿入する際の"Incorrect string value"エラーの原因と解決策

MySQL に JDBC 経由で UTF-8 文字列を挿入しようとすると、"Incorrect string value" エラーが発生することがあります。このエラーは、文字列データがデータベースの文字コードと互換性がないことが原因で発生します。...


WAMPでMySQLからMariaDBへ:スムーズな移行を実現するためのヒントとコツ

WAMPサーバーでMySQLをMariaDBに置き換えるには、以下の手順に従ってください。準備WAMPサーバーを停止します。WAMPサーバーの管理画面を開き、「Stop All Services」ボタンをクリックして、すべてのサービスを停止します。...