The way to see what's happening is to (a) create a stripped-down test case, and (b) do a SELECT *
so you can see what you're getting back in the other columns, that's causing the repetition.
So, I did this:
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;
Then I took a simpler version of your query:
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')
None of the other stuff could make things any worse, right? So it's irrelevant. What do I get when I run this? 9 copies of 1|old
, and 12 copies of 2|new
.
So, let's change it to see the whole row:
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, now you can see the problem, let's see why it's happening. Is each of these rows supposed to be there? In other words, should you see a 1|old
if at least one of the first three combinations are there?
If not, which ones shouldn't be causing it? You need to filter something out in either the WHERE
or the JOIN
.
If so, then you need a GROUP BY
to merge together the relevant fields, or an OR
somewhere, more likely the first.
Step through all of the groups asking the same question. If you get to the point where you need a GROUP BY
on the columns you're actually displaying, it's simpler to just use a SELECT DISTINCT
.
You also might want to step back and ask whether you really want a full JOIN
of long_summary with summary with long_summary. That's 8*3*8=192 rows that you've filtered down to 21. Does that make sense, or did you only expect, say, 24 rows to filter down? If the latter, you've got the JOIN
wrong. Either one of those JOIN
s shouldn't be there at all, or it should be a one-to-one instead of one-to-many JOIN
, or something else is wrong with it.
By the way, you might be able to tell from my test above that I used sqlite3
rather than mysql
, just because it's a lot simpler to get and running. I doubt that makes any difference, but if you test in mysql
and see different results, by all means let me know.