プロが教えるわが家の防犯対策術!

SQLで違うテーブルの値を比較して値に差があるレコードを抽出したいのですがヒントをいただけないでしょうか。
下に例を作ってみました。(テキストに貼りなおしてもらうと見易くなると思います)
<Aテーブル>
A1A2A3A4A5
------- ------- ------- ------- ----------
XXXXXXX XX1ABC32009/05/08
WWCWWCW WW2CCB12008/03/21
DDDDDDD DD1JPN52007/08/08
GGGGGGG GX9SOX21977/01/04
FFFFFFF USJNPB32001/09/11


<Bテーブル>
B1B2B3B4B5
------- ------- ------- ------- ----------
XXXXXXX XX1ibichaoshimu2002/07/05
XXXXXXX XX1takeshiokada2005/07/15
XXXXXXX XX1kamoshu1857/09/25
WWCWWCW WW2waowao2008/10/22
DDDDDDD DD1uihhh2006/06/30
DDDDDDD DD1jojoj x5xx1999/09/09
DDDDDDD DD1momohara2005/03/07
DDDDDDD DD1itaiu-2003/12/22
DDDDDDD DD1komanogoal2007/04/26
GGGGGGG GX9 damerecord2009/11/14
FFFFFFF USJ ikitai1995/08/15
FFFFFFF USJ sstebuspi2004/01/05
FFFFFFF USJ bbpp2009/08/23

A1とB1は主キー、A2とB2は副キーです。
Aテーブルの「A4」カラムにはBテーブルのレコード数を持っています。(主キー、副キーが同じものの)
しかし、よくよく見るとAテーブルの「GGGGGGG」のA4には「2」のはずなのにBテーブルには実際にレコードは1つしかありません。
こういう状態になってしまっているのを割り出したいのですがどのようにA4とBテーブルで数があってないものを抽出できるでしょうか。
よろしくお願いいたします。

「SQLで違うテーブルの値を比較して値に差」の質問画像

A 回答 (4件)

SELECT A.* FROM Aテーブル A


INNER JOIN
TABLE(SELECT B1,B2,COUNT(*) SU
FROM Bテーブル GROUP BY B1,B2) B
ON A.A1=B.B1 AND A.A2=B.B2
AND A.A4<>B.SU

または

WITH B(B1,B2,SU) AS
(SELECT B1,B2,COUNT(*) SU
FROM Bテーブル GROUP BY B1,B2)
SELECT A.* FROM Aテーブル A
INNER JOIN B ON A.A1=B.B1
AND A.A2=B.B2 AND A.A4<>B.SU

こんなのでどうでしょうか?
後者の方が標準的(他のDBシステムでも
使える可能性が高い)かと思います。
    • good
    • 1
この回答へのお礼

後者のものが使うこと出来ました
大変参考になりました
ありがとうございます!

お礼日時:2010/09/05 09:21

No.1です。


自分への返信の後半部分はNo.2さん宛のものですかね?
DB2は触ったことがないのですが、MINUSの代わりに EXCEPT を使えばよさそうです。

SELECT
A1,A2,A4
FROM Aテーブル
EXCEPT
SELECT
B1,B2,COUNT(*)
FROM Bテーブル
GROUP BY B1,B2
    • good
    • 1
この回答へのお礼

ありがとうございます 助かりました!

お礼日時:2010/09/05 09:20

考え方を整理します。


(1)BテーブルのB1、B2をキーとして件数を取得
(2)Aテーブル上で同じキーを持ち、かつ(1)の数と
  A4の値が異なるものを抽出

SELECT A.* FROM Aテーブル A
INNER JOIN
(SELECT B1,B2,COUNT(*) SU
FROM Bテーブル GROUP BY B1,B2) B
ON A.A1=B.B1 AND A.A2=B.B2
AND A.A4<>B.SU
    • good
    • 2
この回答へのお礼

回答ありがとうございます。
Oracleで上記のような結果を得たいと思っていた次第なのですが、私が間違いをしておりました。
DB2 9.5が大元になっており一部のデータをOracleへコピーしています。
Oracle側はBテーブルを持っていないためOracleではそもそも比較しようがないことがわかりました。
そこで大元のDB2でやってみたのですが、どうやらせっかく御教示いただいたSQLがエラーになってしまします。

意味がよくわからなくて大変申し訳ないのですが、ご回答いただいたSQLの構文でJOINの後に“(”があると
無効な識別子みたいなエラーを吐き出します。
規格とかが根本から違うのでしょうか?

本当にポカミスですみません。。。

お礼日時:2010/08/24 21:26

記載の内容が全てで難しいこと考えなくていいなら、minusを使ってはいかがでしょうか?



SELECT
A1,A2,A4
FROM Aテーブル
MINUS
SELECT
B1,B2,COUNT(*)
FROM Bテーブル
GROUP BY B1,B2

これでBテーブルの件数とA4の値が一致しないAテーブルのレコード(全項目ではないですが)が抽出できます。

余談ですが、B1は主キーとは言わないです。主キーとはテーブル内の一意のレコードを特定できるものを言います。
あと、Oracleのバージョンも書いた方がいいと思います。バージョンによって使用できるSQLも違ってきますので。
    • good
    • 1
この回答へのお礼

回答ありがとうございます。
Oracleで上記のような結果を得たいと思っていた次第なのですが、私が間違いをしておりました。
DB2 9.5が大元になっており一部のデータをOracleへコピーしています。
Oracle側はBテーブルを持っていないためOracleではそもそも比較しようがないことがわかりました。
そこで大元のDB2でやってみたのですが、どうやらせっかく御教示いただいたSQLがエラーになってしまします。

意味がよくわからなくて大変申し訳ないのですが、ご回答いただいたSQLの構文でJOINの後に“(”があると
無効な識別子みたいなエラーを吐き出します。
規格とかが根本から違うのでしょうか?

本当にポカミスですみません。。。

お礼日時:2010/08/24 21:26

お探しのQ&Aが見つからない時は、教えて!gooで質問しましょう!

このQ&Aを見た人はこんなQ&Aも見ています

関連するカテゴリからQ&Aを探す


このQ&Aを見た人がよく見るQ&A