2011-06-17 13 views
2

に参加私は2つのテーブルがあります。SQLクエリが参加し、INNERが

TableA  TableB 
id   id 
amt   amt 
idUser  idTableA 

をのは、以下のデータがテーブルAにあるとしましょう:

1 10 1 
2 20 1 
3 30 1 
4 40 2 
5 50 3 
6 60 4 
7 70 4 

と、次のデータがあります表B:

1 10 1 
2 20 2 
3 21 2 
4 51 5 
5 70 7 

すべてのフィールドはNULL可能ではありません。

私は(TableB.idTableAフィールドを介して)TABLEBへの「リンク」を持っていないテーブルA内のどの項目を知りたい場合は、私はこのクエリを行うことができます。

SELECT a.id, a.amt 
FROM TableA a LEFT JOIN TableB b on b.idTableA = a.id 
WHERE b.idTableA IS NULL 

、それは次のように返します。

3 30 
4 40 
6 60 

私は私が何ができるか、AMT値は、各テーブルで同一でないいる(TABLEBへのリンクを持っている)TableAの中のアイテムを知りたい場合は :

SELECT a.id, a.amt, b.amt 
FROM TableA a INNER JOIN TableB b on b.idTableA = a.id 
WHERE a.amt <> b.amt 

、それが返されます:

2 20 21 
5 50 51 

今、私は次のないクエリをしたいと思います:TableAの中に自分のエントリの一部だけがあることを意味TableBのとのリンクを(持っているidUsersを返し idUserの場合、2つのテーブル間にリンクのないテーブルA内にいくつかのエントリが存在しなければならず)、少なくとも1つのエントリがリンクされているラインのうち2つのテーブル間で異なる量を有する。

私の例では、TableAの3番目のエントリが最初の条件(リンクのないエントリ)を満たし、金額が異なるエントリが存在するため(この値にリンクされているため)、idUser 1が返されますidTableA 2は、それが2つのテーブル間のリンクされないラインを有していないためにuserId 2が返されることはありません

それは持っていないので、

のuserId 3が返されない)テーブルBに21対テーブルAに20を量でありますTableBのリンクなしの表A

userId 4は返されません。リンクがない表Aでは1行、リンク付きの1行もあるので、リンク付きの行は2つの表間で同じ量になります。

だから本当にそれは2つの初期のクエリのミックスです...あなたの入力し、基本的な書式や言語のための私の謝罪のため

おかげで、私はこれが十分に明確であると思います:)

+0

あなたのクエリは 'WHEREb.idTableA IS NULL'で終わるともTableAids 4と6を返すべきだと思います。 – therealmitchconnors

答えて

4
with loners as (
SELECT a.* 
FROM TableA a 
LEFT JOIN TableB b on b.idTableA = a.id 
WHERE b.idTableA IS NULL 
), 
diffs as (
SELECT a.* 
FROM TableA a 
INNER JOIN TableB b on b.idTableA = a.id 
WHERE a.amt <> b.amt 
) 
select loners.userID 
FROM loners 
INNER JOIN diffs on LONERS.userID = DIFFS.userID 
+0

+1これは私が思ったよりも簡単でした...もっと良い(パフォーマンス上の)実装、それを行う最善の方法は? – ibiza

+0

パフォーマンスは全体的に大きく異なります。 1つは、スピード、最小メモリ使用量、最小CPU使用量、最小io使用量を探していますか?あなたは何のために最適化していますか?また、基礎となるスキーマ、使用しているインデックス、存在しているハーウェア、天気予報などについては – therealmitchconnors

+1

ですが、これは副問合せの使用と同じですか?可能な限りサブクエリを避けることは良いと思っていましたし、サブクエリなしでパフォーマンスの良いクエリを使用しても同じ結果が得られるはずです。 – ibiza

1
SELECT a.idUser 
FROM 
(SELECT a2.id, a2.amt, a2.idUser 
    FROM TableA AS a2 
    LEFT JOIN TableB AS b2 
    ON b2.idTableA = a2.id 
    WHERE b2.idTableA IS NULL 
) AS a 
INNER JOIN TableB AS b 
ON b.idTableA = a.id 
WHERE a.amt <> b.amt; 

実際にこれがもっと効率的かどうかは分かりませんが、ここでどのようにしたらよいでしょうか。

+0

あなたの貢献に感謝します:) – ibiza

関連する問題