看看发生了什么的方法是(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
和2|new
12份。
所以,让我们改变它看到整排:
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
?
如果不是,哪个不应该导致它?您需要在WHERE
或JOIN
中筛选出某些内容。
如果是这样,那么你需要一个GROUP BY
来合并相关的字段,或一个OR
某处,更可能是第一个。
逐步通过所有组询问相同的问题。如果您在实际显示的列上达到需要GROUP BY
的点,则只需使用SELECT DISTINCT
即可。
您也可以退后一步,询问您是否真的想要long_summary的完整JOIN
以及带有long_summary的摘要。这是8 * 3 * 8 = 192行,您已经过滤到21行。这是否有意义,或者你只期望,例如,24行来过滤?如果是后者,你得到了JOIN
错误。这些JOIN
中的任何一个都不应该存在,或者它应该是一对一的而不是一对多的JOIN
,或者其他问题是错误的。
顺便说一下,从上面的测试中可以看出,我使用sqlite3
而不是mysql
,只是因为它的获取和运行要简单得多。我怀疑这有什么不同,但如果你在mysql
进行测试并看到不同的结果,请通过任何方式告诉我。
您确定您的表格中实际上没有重复的行吗?因为如果你没有任何主键或唯一键,没有什么能阻止你反复插入相同的东西。 – abarnert
对于第一个表的每个记录,第二个表中可能有多个行,因此它将返回第二个表的第二个表的多行重新排列第一个表的行。 –
summary.id是主键 –