本ページはプロモーションが含まれています。 DB

DB(MySQL)で他のテーブルからデータをコピーする方法

2023年4月1日

今回はデータベーステーブル間のデータコピー、特に一部のレコードをコピーする方法について取り扱います。

既存テーブルのコピーだけであれば、phpMyAdminやadminerなどのGUIが充実しているため難しくはありません。
ほぼSQLを書かずに実行できます。

コピーするデータの絞り込みや加工など、より実践的な内容を取り扱います。

この記事で分かること

  • データベース間でデータをコピーする方法
  • コピーするデータを加工する方法

サンプルのテーブルについて

クラス図

今回のテーマをイメージしてもらうため、まずはサンプルデータの構造を考えてみます。
複雑にしても大変なのでかなり簡素なものにします。

・社員テーブル(元のテーブル)

社員ID(INT)

社員名(VC255)

通勤手段(VC255)

退社済みフラグ(tinyINT)

1

佐藤

徒歩

 

2

田中

徒歩

 

3

鈴木

自転車

1

4

山田

公共交通機関

1

5

斉藤

自動車

 

・社員テーブル2(コピー先のテーブル)

社員ID(INT)

社員名(VC255)

通勤手段番号(INT)

1

佐藤

1

2

田中

1

5

斉藤

4

・通勤手段テーブル(※作成済みとする)

通勤手段番号(INT)

通勤手段の詳細(VC255)

1

徒歩

2

自転車

3

公共交通機関

4

自動車

ざっくりまとめると、次の変更を加えたものをコピー後のテーブルとします。

  • 退社済みの社員データは削除し管理しないようにする
  • 通勤手段をリレーションテーブルで管理する

テーブル間のデータ挿入は「INSERT」文で行える

データベースディスク

テーブル同士でデータを挿入する場合は、通常の追加と同じく「INSERT」文を使用します。

特定の行・列だけコピーする構文はなく、SELECTやWHEREで絞り込みます。

まずはそのまま新しいテーブルにコピーする例をみてみましょう。


INSERT INTO 社員テーブル2 (
    `社員ID`,
    `社員名`,
    `通勤手段番号`
) SELECT
    `社員ID`,
    `社員名`,
    -- ※通勤手段番号は型違いのため固定値
    0 as num
FROM 社員テーブル;

上の例では、「社員ID」と「社員名」はそのまま、「運動手段」は文字列と数値で型が違うためダミーデータを挿入しています。

できあがるテーブルは以下の通りです。

社員ID(INT)

社員名(VC255)

通勤手段番号(INT)

1

佐藤

0

2

田中

0

3

鈴木

0

4

山田

0

5

斉藤

0

ほぼ1つ目の社員テーブルから変わっていません。
ここから加工を加えていき、テーブル2の形になるようにしていきます。

INSERTするデータを加工する場合は「CASE」文を使う

フローチャートの条件分岐

データの加工をする場合も、通常のSQLと同様にCASEを使うことができます。

今回のサンプルでは、「通勤手段」(文字列)を「通勤手段番号」(INT)に変換します。

まずはSQL文を見てみましょう。


INSERT INTO 社員テーブル2 (
    `社員ID`,
    `社員名`,
    `通勤手段番号`
) SELECT
    `社員ID`,
    `社員名`,
    CASE
        WHEN `通勤手段` = '徒歩' THEN 1
        WHEN `通勤手段` = '自転車' THEN 2
        WHEN `通勤手段` = '公共交通機関' THEN 3
        WHEN `通勤手段` = '自動車' THEN 4
        ELSE 0
    END AS 通勤手段番号
FROM 社員テーブル
WHERE `退社済みフラグ` <> 1;

先ほどの例と比べると、INSERTは同じですがそのあとの構文が異なります。

ちなみにas句の別名は、予約語以外であれば何でもいいです。

変更点1:SELECTの結果をCASEで分岐させる

このCASE文では、「通勤手段」のSELECT結果に対して分岐を設けています。
条件部分の短縮もできますが、今回は採用しませんでした。

元の「社員テーブル」に直接文字列で登録されていた通勤手段を、「社員テーブル2」ではリレーションしている「運動手段テーブル」のIDに置換しています。

また、通常のCASE文と同じように、式や関数も使用することが可能です。

変更点2:コピーするテーブルをWHEREで絞り込む

始めにコピーする行の条件を確認します。
「社員テーブル」の「退社済みフラグ」が有効(=退社済み)の社員は管理しない、というものです。

WHEREの部分は見ての通りですが、フラグが有効なもの以外を抽出するように指定しています。

null値の有無にもよりますが、一致構文にしても勿論問題ありません。

テーブル間のデータコピーは、INSERTとSELECTを組み合わせて使おう!

DBのコピーイメージ

 

今回は、データベーステーブル間のコピー方法についてご紹介しました。

SQLを見ていただけると分かると思いますが、基本的なINSERT文とSELECT文を組み合わせるような形になります。

SELECTで抽出した結果を挿入するような感じなので、先にSELECT部分だけ実行してみた方が分かりやすいかもしれません。

サンプルでは使いませんでしたが、JOINを使うとより効率的にできますので良かったら考えてみてください。

おすすめ記事をCHECK!

aptがあればapt-getは不要? 1

Debian系のパッケージ管理として「apt」が登場してから、時々「apt-getは不要!」という話を聞くことがあります。 結論から言うと、公式では「使い分けよう」が正解です。 公式の方では、次のよう …

2023年2月時点。新しくなったAWSシークレットキーの作り方。 2

AWSの管理画面は、結構頻繁に変わりますよね。 以前まではIAMとシークレットアクセスキーを同時に作成できましたが、今はその機能が見当たらなくなりました。 結論としては、IAMのユーザーを作成後に、設 …

初心者におすすめ! 失敗しないレンタルサーバー3選。 3

ある程度経験がないと、レンタルサーバーはどれも同じに見えるかもしれません。 しかし、選び方次第で、設定に2倍、3倍の時間がかかってしまうこともあります。 そこで今回は、コスパ・使いやすさに特化した3つ …

-DB
-