2016-12-16 51 views
2

表示されないテーブルからすべてを選択するSQL。は、私は3つのテーブルを持っている第二のテーブルに

各一致IDテーブルのいずれかの一致テーブルには、多数のエントリがあります。つまり、両方のテーブルの各ユーザに多くの一致があります。

どちらの一致テーブルにもないユーザーをすべて選択する必要があります。

私はこのクエリを試してみました -

SELECT * FROM Users 
JOIN Matches_A ON Users.id = Matches_A.id2 
JOIN Matches_B on Users.id = Matches_B.id2 
WHERE Matches_A.id1 != $userid 
AND Matches_B.id1 != $userid; 

これは動作しません。

問題は、同じid2でid1が異なる一致テーブルにエントリがあることです。つまり、id1とuseridが一致する行を除外しても、id1がuser_idと一致しない同じユーザーを持つ別の行があるため、そのユーザー(id2)が返される可能性があります。

これが意味をなさない場合は、言い換えてください。私が返すことを望まないすべてのものを選択するのは簡単でしょう。

SELECT * FROM Users 
JOIN Matches_A ON Users.id = Matches_A.id2 
JOIN Matches_B on Users.id = Matches_B.id2 
WHERE Matches_A.id1 != $userid 
AND Matches_B.id1 = $userid; 

望ましくない行をすべて返します。どのように私は他のすべての行を取得するクエリを記述することができます。

P.S.サブクエリでこれを行うのはかなり簡単ですが、特に3つのテーブルでは遅くなることが心配です。

答えて

0

not inまたはnot existsの代わりjoinを考える:

SELECT * 
FROM Users u 
WHERE u.id NOT IN (SELECT a.id2 FROM Matches_A) AND 
     u.id NOT IN (SELECT b.id2 FROM Matches_B); 

このバージョンでは、id2は、いずれかのテーブルでNULL決してしないことを前提としています。

0

添付の画像から解決策を試してください。左結合を使用し、nullを使用することについてのアイデアが得られます。 これが助けてくれれば教えてください。 https://i.stack.imgur.com/YR5aK.png

0

また

SELECT u.* 
FROM Users u 
WHERE NOT EXISTS (SELECT a.id2 FROM Matches_A a WHERE a.id2 = u.id 
        UNION ALL 
        SELECT b.id2 FROM Matches_B b WHERE b.id2 = u.id) 
+0

EXCEPT使用することですをEXISTS、NOT を試すことができます。 – dmg

+0

サブクエリの結果が非常に大きい場合はEXISTSが高速に実行され、サブクエリの結果が非常に小さい場合はNOT INが高速になる場合は、サブクエリによって返される行数によって異なります。大きなボリュームのデータがない場合は、anyを使用できます。 – Susang

+0

クエリは、ユーザーのすべてのタプルに対して1つのサブクエリを実行する必要があります。サブクエリが返す結果の数は関係ありません。問題は、それを実行しなければならないということです。 – dmg

0

最も簡単な解決策は、ユーザーがタプルをたくさん持っている場合は、このクエリが極端に遅くなるだろう

WITH Subset as (SELECT id from users EXCEPT 
       (SELECT id2 from Matches_A 
       UNION 
       SELECT id2 from Matches_B)) 
SELECT * FROM Users NATURAL JOIN Subset; 
+0

EXCEPTはMYSQLで動作すると思いますか?質問を正しく読んで、TAGで見てみるだけで、どんな質問にも答えてみてください。 – Susang

+0

私はそうは思わない。それはmysqlユーザーの損失です。 :) – dmg

関連する問題