【问题标题】:NOT IN converted to LEFT JOIN giving different resultNOT IN 转换为 LEFT JOIN 给出不同的结果
【发布时间】:2015-03-10 07:21:35
【问题描述】:

请帮助以下查询

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

【问题讨论】:

  • 欢迎来到 SO,请在标签和标题中指定查询语言。
  • 您使用的是哪个 DBMS?
  • 我使用的是 SYABSE 15.7
  • 我敢打赌,LEFT JOIN 正在生成一些带有 NULL 值的结果,这些结果被排除在 where 子句中,因为 NULL 不能等于任何东西。
  • 是的,我得到了 NULL ,但是你能告诉我为什么当我将它用作 (2001,2002,2003) 时我没有得到 NULL 值

标签: sql join sybase


【解决方案1】:

对于使用左联接的 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) )

【讨论】:

  • 'select A.* from processes_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' 那么上面的查询给出了超过 76 K 的结果。但是 not exists 工作正常。我要去not exists
【解决方案2】:

无论条件是否匹配,LEFT JOIN 都会返回“左侧”表中的所有行,这就是您获得“额外”行的原因。

INNER JOIN可能给你相同的行数,但如果“右手”表中有 多个匹配,那么你仍然会得到行数超出您的预期。

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

【讨论】:

  • 感谢您的评论。我不想硬编码使用 LEFT JOIN 的值。好吧,如果那不能提高性能,我可以使用子查询
  • 如果您有性能问题,EXISTSNOT EXISTS 可以 解决它(在某些情况下与NOT IN 相比)。 Please check the syntax in the documentation.
  • 所以我打算使用 [code] select A.* from processes_h where c_type not in (select convert(int,n_index) from index_m where n_index '0')
  • @ArunKumar 我认为这是最简单和最直接的。你有什么理由不想使用它吗?
  • @Stanley,我毫不犹豫地使用子查询,因为它会降低性能
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2013-11-18
  • 1970-01-01
  • 2011-01-02
  • 1970-01-01
  • 2022-07-06
  • 1970-01-01
相关资源
最近更新 更多