2014-10-04 67 views
2

我有一个人表:如何摆脱SQL中的重复行交叉联结查询结果?

PERSON

要获得有谁是他们的年龄不足5年之间的差异人员名单,我尝试:

SELECT * 
FROM PERSON p1 
CROSS JOIN PERSON p2 
WHERE p1.psn_id <> p2.psn_id 
    AND p1.psn_age - p2.psn_age <= 5; 

所以我就:

RESULT

正如你所看到的,第二行是一样的第一。我的问题是如何摆脱重复的行?

回答

4
SELECT * FROM PERSON p1 
CROSS JOIN PERSON p2 
WHERE 
    p1.psn_id < p2.psn_id 
AND 
    ABS(p1.psn_age - p2.psn_age) <= 5; 
+1

这并不实际工作,即使语法是固定的,它产生的结果相同'交叉join'。 – md4 2014-10-04 08:41:28

+1

你是对的,但我很确定我之前做过这件事,并且离开了加入,我正在查看我的文件,看看我是否找到了某些东西......我会回来让你知道:-) – NotGaeL 2014-10-04 08:44:27

+0

是的,它产生相同的结果 – Jalil 2014-10-04 08:46:17

3

试试这个:

select 
    * 
from 
    PERSON a 
    inner join 
    PERSON b on a.psn_id < b.psn_id and abs(a.psn_age - b.psn_age) <= 5; 

它将把旧人就离开了。如果出于任何原因,您宁愿选择其他方式,请将a.psn_age - b.psn_age更改为b.psn_age - a.psn_age

更新,我已经加入年龄87,84和50的三个新的人,以确保87和84相互匹配,而50不匹配任何验证了这一点。

+0

这样我摆脱每一个第一和第二行,但我只想摆脱其中的一个! – Jalil 2014-10-04 08:54:28

+0

对不起,我错过了你的要求。更新。 – md4 2014-10-04 08:57:27

2

不仅第二线基本上是第一个重复的,而且在你的输出的第三和第四线不符合要求,因为这些人的年龄之差大于5

我相信这应该是足够指定的差异不应该是否定的:

SELECT * 
FROM PERSON p1 
CROSS JOIN PERSON p2 
WHERE p1.psn_id <> p2.psn_id 
    AND p1.psn_age - p2.psn_age BETWEEN 0 AND 5 
;
0

我想你需要左联接,如果我理解正确的:

试试这个:

SELECT * 
FROM PERSON p1 
LEFT JOIN PERSON p2 
on p1.psn_id < p2.psn_id 
    AND ABS(p1.psn_age - p2.psn_age) <= 5; 
+0

我不记得是否有一个支持'LEFT JOIN'而没有'ON'的SQL产品。无论如何,如果你看看[elcodedocle的回答的历史](http://stackoverflow.com/posts/26191119/revisions),你会发现你目前的建议也是他的第一个建议(并且它没有工作如评论所见)。 – 2014-10-04 09:29:45

+0

@Andriy M.是的,我忘了添加“ON”子句,我刚刚更新了答案,谢谢。在elcodedocle的答案中,他有用户交叉连接,我认为解决方案只是使用左连接 – 2014-10-04 09:38:00