MySQL でカラムの値で重複する場合に1つを残して削除する方法と絞り込み

PR

MySQLで特定のカラムのデータが重複する場合に実行するクエリ。重複を取り除いてSELECTと重複するものを1つだけ残して他は削除する方法。データベースにデータを追加していっている時に、データが重複してしまう場合がある。ほか、データ重複の検証の作業を飛ばして、あとから重複を消せばいいやという時に使える。

 

 

MySQLで特定のカラムの値が重複する場合の処理

 

 

重複を取り除いて表示する

SELECT * FROM 対象のテーブル GROUP BY 対象のカラム

対象のカラムで、重複を取り除いてテーブルに有る全件のレコードを表示する。

GROUP BY で対象のカラムを指定することで、そのカラムでの重複しないようにします

 

 

重複を取り除いて一つだけ残してテーブルを更新する

CREATE TABLE テーブル2 as SELECT * FROM テーブル GROUP BY 対象のカラム;
DROP TABLE テーブル;
ALTER TABLE テーブル2 RENAME TO テーブル;

こちらは、テーブルにある対象のカラムで重複しているものを取り除いてテーブルを更新するもので、一行目では新しくテーブルを作っています、そのテーブルに 最初に紹介した重複を除いた全レコードを入れたものです。2行目では元のテーブルを削除しています。3行目では新しく作ったテーブルを元のテーブル名にすることで テーブルを置き換えています。

 

流れ

  • テーブル作る
  • 作るテーブルのデータ指定
  • 元のテーブル消す
  • 作ったテーブルをリネーム
  • 重複のないテーブルになる

テーブルそのものを置き換えているので、あまり多様は出来ないですがメンテナンス的な使い方が出来るかと思います。

 

PHPで実行する場合 (PDOを使ったDB接続)

$db_host   = "localhost";
$db_name   = "database name";
$db_id     = "id";
$db_pass   = "password";
$db_table  = "table name";
$db_unique = "Column name";


//DB接続
try {
  $pdo = new PDO(
    "mysql:dbname=$db_name;host=$db_host","$db_id","$db_pass",
    array(
      PDO::MYSQL_ATTR_INIT_COMMAND => "SET CHARACTER SET `utf8`"));
} catch (PDOException $e) {
  die($e->getMessage());
}



$stmt = $pdo -> prepare("
CREATE TABLE ".$db_table."x as SELECT * FROM ".$db_table." GROUP BY ".$db_unique.";
DROP TABLE ".$db_table.";
ALTER TABLE ".$db_table."x RENAME TO ".$db_table.";
");
$stmt->execute();

$pdo = null;

こんな感じになります。DB保存のプロセスのどこかに、重複を削除するプロセスを導入しても有りかと思います。基本的に、重複を望まないのなら重複しないように保存する方法を考えて完璧にこなすのがベストですが、重複確認の度にDBとの接続がネックになる場合や重複自体に外がない場合はDB接続を閉じる前にこういったプロセスを入れてもいいかなと思います。

 

PR

COMMENT

  1. hide

    > SELECT * FROM 対象のテーブル GROUP BY 対象のカラム
    これはSQLで以下のようなエラーになりますよ。
    「ERROR 1064 (42000): You have an error in your SQL syntax; check the manual that corresponds to your MySQL server version for the right syntax to use near ‘group by code’ at line 1」
    GROUP BYでまとめる場合は、まとめたカラムか関数しか出力できません

  2. 管理人

    hideさん

    コメントありがとうございます
    エラーは構文エラーが出ているのかな?、MYSQLの予約語とかぶっているのでしょうか?

    予約語との重複をさけるために
    SELECT * FROM `対象のテーブル` GROUP BY `対象のカラム`
    としておいたほうがいいですね

    mysqlでは、この方法が使えるみたいで
    ほかでは、GROUP BY 以外で指定したものは消えてしまうようですね

コメントを残す

PR

9ineBBの管理人が運営するサイト

WDG WEB DESIGN GALLERY ウェブデザインギャラリー