SQL Server - 二つのテーブルのデータが完全に同じか比較する方法

ここでは、SQL Server で二つのテーブルのデータが完全に同じか比較する方法をご説明します。

テーブルの差分を比較する方法はいろいろありますが、今回は EXCEPT と JOIN を使う方法をご紹介します。

二つのテーブルは全く同じ構造で、ユニークで NOT NULL のキーとなるカラムが存在する前提でおこないます。

二つのテーブルを比較するサンプルデータを生成する

二つのテーブルのデータを比較するために、以下のスクリプトを実行して Student1 と Student2 テーブルを作ります。

StudentID がプライマリーキーです。

※ Student1 と Student2 テーブルがデータベースに既に存在している時は削除されてしまいますのでご注意ください。

IF OBJECT_ID(N'dbo.Student1', N'U') IS NOT NULL DROP TABLE Student1;
IF OBJECT_ID(N'dbo.Student2', N'U') IS NOT NULL DROP TABLE Student2;

CREATE TABLE Student1 (
   StudentID INT NOT NULL IDENTITY(1,1) PRIMARY KEY,
   FirstName VARCHAR(50) NULL,
   LastName VARCHAR(50) NULL,
   Birthday DATE NULL,
   Gender CHAR(1) NULL
);

CREATE TABLE Student2 (
   StudentID INT NOT NULL IDENTITY(1,1) PRIMARY KEY,
   FirstName VARCHAR(50) NULL,
   LastName VARCHAR(50) NULL,
   Birthday DATE NULL,
   Gender CHAR(1) NULL
);

INSERT INTO Student1
  (FirstName, LastName, Birthday, Gender)
 VALUES
  ('Taro', 'Yamada', '2011-02-10', 'M'),
  ('Hanako', 'Tanaka' ,'2010-12-30', 'F'),
  ('Yuko', 'Suzuki', '2010-07-07', 'F'),
  ('Makoto', 'Sato', '2011-03-12', 'M'),
  ('Hiroki', 'Takagi', '2010-04-05', 'M');


INSERT INTO Student2
  (FirstName, LastName, Birthday, Gender)
 VALUES
  ('Taro', 'Yamada', '2011-02-15', 'M'),
  ('Hanako', 'Tanaka' ,'2010-12-30', 'F'),
  ('Yuko', 'Suzuki', '2010-07-07', 'F'),
  ('Makoto', 'Sato', '2011-03-12', 'M'),
  ('Hiroki', 'Takagi', '2010-04-05', 'M'),
  ('Yuka', 'Kimura', '2012-03-27', 'F');

以下の緑の部分が違っている箇所です。

SQL Server - 二つのテーブルのデータが完全に同じか比較する方法 1


EXCEPT を使って二つのテーブルのデータを比較する

まずは、EXCEPT 演算子 を使って二つのテーブルのデータが完全に同じかを比較する方法です。

EXCEPT 演算子は EXCEPT の左側の結果セットに存在していて、右側の結果セットには存在していない値のみを返してくれるオペレータで、構文は次の通りです。

[ クエリー 1 ] EXCEPT [ クエリー 2 ]

EXCEPT 演算子の結果セットは DISTINCT な値を返します。

それぞれのクエリーは、カラムの数、順番が一致 していなければなりません。

また、データ型も一致しているか、暗黙に同じ型に変換可能 なものでなければなりません。


EXCEPT 演算子を使って Student1 に存在していて、Student2 に存在しないデータと、Student2 に存在していて Student1 に存在しないデータを確認します。

SELECT	*
FROM	Student1
EXCEPT
SELECT	*
FROM	Student2;

SELECT	*
FROM	Student2
EXCEPT
SELECT	*
FROM	Student1;

SQL Server - 二つのテーブルのデータが完全に同じか比較する方法 2

二つのテーブルのカラム数、データ型、カラムの順番が一致しているので * で比較できます。

EXCEPT を使うと DISTINCT な値で比較するので、全く同じ値のレコードが片方のテーブルに多く存在していたとしても、差分として出てきません。

ですが、プライマリーキーカラムが含まれているため、ひとつのテーブルに重複データが存在しないので大丈夫です。


もし、テーブルが同じかどうかを取得したいのであれば、上の結果セットの存在を確認することで取得できます。

IF EXISTS
  (SELECT *
   FROM   Student1
   EXCEPT
   SELECT *
   FROM   Student2)
 OR EXISTS 
  (SELECT *
   FROM   Student2
   EXCEPT
   SELECT *
   FROM   Student1)
BEGIN
   SELECT 'Different' AS Result;
END
ELSE
BEGIN
   SELECT 'Same' AS Result;
END

SQL Server - 二つのテーブルのデータが完全に同じか比較する方法 3

JOIN を使って二つのテーブルのデータを比較する

次は JOIN を使って、二つのテーブルのデータが完全に同じか比較する方法です。

ユニークで NOT NULL なキーをカラムを使って、二つのテーブルを結合します。


まず、キーとなるカラムで INNER JOIN してそれ以外のカラムの値がひとつでも等しくないレコードを抽出します。

等しいかどうかをチェックする際には値に NULL があるとその条件式が TRUE になることはないので気をつけてくださいね。

次に、二つのテーブルをキーとなるカラムで LEFT JOIN して、左側のテーブル 1 にあって右側のテーブル 2 にないレコードを抽出します。

そして、テーブルを反対にして LEFT JOIN して、左側のテーブル 2 にあって右側のテーブル 1 にないレコードを抽出します。

テーブルを反対にせずに RIGHT JOIN を使っても大丈夫です。


この三つのクエリーを実行することで、二つのテーブルのデータで一致していない差分のレコードを取得することができます。

SELECT T1.*,
       T2.*
FROM   Student1 AS T1
          INNER JOIN Student2 AS T2
            ON T1.StudentID = T2.StudentID
WHERE  ISNULL(T1.FirstName, '') <> ISNULL(T2.FirstName, '')
       OR ISNULL(T1.LastName, '') <> ISNULL(T2.LastName, '')
       OR ISNULL(T1.Birthday, '1900-01-01') <> ISNULL(T2.Birthday, '1900-01-01')
       OR ISNULL(T1.Gender, '') <> ISNULL(T2.Gender, '');

SELECT T1.*,
       T2.*
FROM   Student1 AS T1
	   LEFT JOIN Student2 AS T2
	      ON T1.StudentID = T2.StudentID
WHERE  T2.StudentID IS NULL;

SELECT T1.*,
       T2.*
FROM   Student2 AS T2
           LEFT JOIN Student1 AS T1
	      ON T2.StudentID = T1.StudentID
WHERE  T1.StudentID IS NULL;

SQL Server - 二つのテーブルのデータが完全に同じか比較する方法 4

もし、テーブルが同じかどうかだけを取得したいのであれば、先ほどの EXCEPT と同様に上の三つのクエリーの結果セットの存在を確認することで取得できますね。

IF EXISTS
  (SELECT *
   FROM   Student1 AS T1
            INNER JOIN Student2 AS T2
               ON T1.StudentID = T2.StudentID
   WHERE  ISNULL(T1.FirstName, '') <> ISNULL(T2.FirstName, '')
          OR ISNULL(T1.LastName, '') <> ISNULL(T2.LastName, '')
          OR ISNULL(T1.Birthday, '1900-01-01') <> ISNULL(T2.Birthday, '1900-01-01')
          OR ISNULL(T1.Gender, '') <> ISNULL(T2.Gender, ''))
 OR EXISTS
  (SELECT *
   FROM   Student1 AS T1
             LEFT JOIN Student2 AS T2
                ON T1.StudentID = T2.StudentID
   WHERE  T2.StudentID IS NULL)
 OR EXISTS
  (SELECT *
   FROM   Student2 AS T2
            LEFT JOIN Student1 AS T1
               ON T2.StudentID = T1.StudentID
   WHERE  T1.StudentID IS NULL)
BEGIN
   SELECT 'Different' AS Result;
END
ELSE
BEGIN
   SELECT 'Same' AS Result;
END

SQL Server - 二つのテーブルのデータが完全に同じか比較する方法 5

以上、SQL Server で二つのテーブルのデータが完全に同じか比較する方法をご紹介しました。

© 2010-2024 SQL Server 入門