何が起こっているかを確認する方法は、(a)簡略化されたテストケースを作成し、(b)SELECT *
他の列で何が戻っているかを確認できるようにすることです。これにより、繰り返しが発生します。
だから、私はこれをしました:
CREATE TABLE summary(id, status, value, time, aperson);
INSERT INTO "summary" VALUES(1,'old',23,'time0','joe');
INSERT INTO "summary" VALUES(2,'new',42,'time1','bob');
INSERT INTO "summary" VALUES(3,'new',32,'time2','mike');
CREATE TABLE long_summary(id, who, comment, alltext);
INSERT INTO "long_summary" VALUES(1,'someone','i say!','some text');
INSERT INTO "long_summary" VALUES(1,'joe','joe likes','some text');
INSERT INTO "long_summary" VALUES(2,'joe','joe likes bob','some text');
INSERT INTO "long_summary" VALUES(3,'joe','joe likes mike','some text');
INSERT INTO "long_summary" VALUES(1,'bob','nice one, joe','some text');
INSERT INTO "long_summary" VALUES(2,'bob','nice one, me','some text');
INSERT INTO "long_summary" VALUES(2,'bob','double nice one, me','some text');
INSERT INTO "long_summary" VALUES(3,'bob','nice one, mike','some text');
COMMIT;
次に、より単純なバージョンのクエリを使用しました。
SELECT l.id,summary.status
FROM long_summary l INNER JOIN summary ON l.id = summary.id INNER JOIN long_summary ON summary.aperson = long_summary.who
WHERE summary.status IN('old','new','waiting')
他のものはどれも事態を悪化させることはできませんよね?したがって、それは無関係です。これを実行すると何が得られますか?の9コピー1|old
、およびの12コピー2|new
。
それでは、行全体が表示されるように変更してみましょう。
SELECT *
FROM long_summary l INNER JOIN summary ON l.id = summary.id INNER JOIN long_summary ON summary.aperson = long_summary.who
WHERE summary.status IN('old','new','waiting')
1|bob|nice one, joe|some text|1|old|23|time0|joe|1|joe|joe likes|some text
1|bob|nice one, joe|some text|1|old|23|time0|joe|2|joe|joe likes bob|some text
1|bob|nice one, joe|some text|1|old|23|time0|joe|3|joe|joe likes mike|some text
1|joe|joe likes|some text|1|old|23|time0|joe|1|joe|joe likes|some text
1|joe|joe likes|some text|1|old|23|time0|joe|2|joe|joe likes bob|some text
1|joe|joe likes|some text|1|old|23|time0|joe|3|joe|joe likes mike|some text
1|someone|i say!|some text|1|old|23|time0|joe|1|joe|joe likes|some text
1|someone|i say!|some text|1|old|23|time0|joe|2|joe|joe likes bob|some text
1|someone|i say!|some text|1|old|23|time0|joe|3|joe|joe likes mike|some text
2|bob|double nice one, me|some text|2|new|42|time1|bob|1|bob|nice one, joe|some text
2|bob|double nice one, me|some text|2|new|42|time1|bob|2|bob|double nice one, me|some text
2|bob|double nice one, me|some text|2|new|42|time1|bob|2|bob|nice one, me|some text
2|bob|double nice one, me|some text|2|new|42|time1|bob|3|bob|nice one, mike|some text
2|bob|nice one, me|some text|2|new|42|time1|bob|1|bob|nice one, joe|some text
2|bob|nice one, me|some text|2|new|42|time1|bob|2|bob|double nice one, me|some text
2|bob|nice one, me|some text|2|new|42|time1|bob|2|bob|nice one, me|some text
2|bob|nice one, me|some text|2|new|42|time1|bob|3|bob|nice one, mike|some text
2|joe|joe likes bob|some text|2|new|42|time1|bob|1|bob|nice one, joe|some text
2|joe|joe likes bob|some text|2|new|42|time1|bob|2|bob|double nice one, me|some text
2|joe|joe likes bob|some text|2|new|42|time1|bob|2|bob|nice one, me|some text
2|joe|joe likes bob|some text|2|new|42|time1|bob|3|bob|nice one, mike|some text
OK、これで問題がわかりました。なぜそれが起こっているのか見てみましょう。これらの各行はそこにあるはずですか?言い換えれば1|old
、最初の3つの組み合わせの少なくとも1つが存在するかどうかを確認する必要がありますか?
そうでない場合、どれがそれを引き起こしてはいけませんか?WHERE
またはのいずれかで何かを除外する必要がありますJOIN
。
もしそうなら、あなたGROUP BY
は関連するフィールド、またはOR
どこか、おそらく最初のフィールドを一緒にマージする必要があります。
同じ質問をするすべてのグループをステップスルーします。GROUP BY
実際に表示している列にが必要な場合は、を使用する方が簡単SELECT DISTINCT
です。
JOIN
また、一歩下がって、long_summaryとsummaryを含むlong_summaryでいっぱいにする必要があるかどうかを尋ねることもできます。これは、21にフィルターダウンした8 * 3 * 8 = 192行です。それは意味がありますか、それとも、たとえば24行だけフィルターダウンすることを期待していましたか?後者の場合、あなたはJOIN
間違っています。それらのいずれかJOIN
がまったく存在しないか、1対多ではなく1対1であるJOIN
か、または他の何かが間違っている必要があります。
ちなみに、上記のテストから、取得と実行がはるかに簡単であるという理由だけで、sqlite3
ではなく使用したことがわかる場合があります。mysql
それが違いを生むとは思えませんが、テストしmysql
て異なる結果が表示された場合は、ぜひお知らせください。