NOT IN转换为LEFT JOIN,给出不同的结果

时间:2015-01-12 13:48:33

标签: sql join sybase

请在下面的查询中提供帮助

select * from processed_h where c_type not in (select  convert(int,n_index) from index_m where n_index <>'0') **-- 902 rows**


select * from processed_h where c_type not in (2001,2002,2003)  **-- 902 rows**


select  convert(int,n_index) from index_m where n_index <>'0'  **--- 2001,2002,2003** 

我尝试将not in转换为LEFT JOIN,如下所示,但它给了我40,000行返回我做错了

select A.* from processed_h A LEFT JOIN index_m B on A.c_type <> convert(int,B.n_index) and B.n_index <>'0' --40,000 + rows

2 个答案:

答案 0 :(得分:0)

LEFT JOIN返回&#34;左手&#34;中的所有行表格无论条件是否匹配,这就是为什么你得到&#34;额外&#34;行。

INNER JOIN 可能会为您提供相同数量的行,但如果&#34;右手&#34;中有多个匹配那么你还会获得比预期更多的行。

如果NOT IN为您提供了预期的结果,那么我就会坚持下去。你可能不会看到加入的重大改进。我改为INNER JOIN的唯一原因是我需要输出中连接表中的列。

答案 1 :(得分:0)

对于使用左连接的等效NOT IN,您需要链接表,就好像链接表中的结果应该是IN结果集一样,然后只选择那些外部的记录加入表没有返回记录 - 就像这样:

select A.* from processed_h A 
LEFT JOIN index_m B on A.c_type = convert(int,B.n_index) and B.n_index <>'0'
WHERE B.n_index IS NULL

但是,使用NOT EXISTS查询可能会获得更好的效果:

select A.* from processed_h A 
where not exists
(select 1 from index_m B where B.n_index <>'0' and A.c_type = convert(int,B.n_index) )