SQL初学者问题:存在位置的意外行为选择1

时间:2018-09-14 06:43:56

标签: sql

我一周前开始使用SQL。抱歉,我有一个“为什么我的代码不起作用”的问题。

请查看对表1和表2的以下三个查询。

A。内部联接(返回2行结果)

select t1.*, t2.* from table1 t1, table2 t2 
where t1.item = t2.item 
and t1.something = t2.something 

B。子查询(返回2行结果)

select t1.* from table1 t1 
where exists (select 1 from table2 t2 
                  where t1.item = t2.item 
                  and t1.something = t2.something)

C。我的代码(预期结果与A.“内部联接”中的结果相同,但要花很多时间才能返回结果)

select t1.*, t2.* from table1 t1, table2 t2 
where exists (select 1 from table2 t2
                  where t1.item = t2.item 
                  and t1.something = t2.something)

为便于参考,每个表的行数如下。

select count(*) from table1 -- (100K)
select count(*) from table2 -- (10K)

有人会教育我知道为什么我的代码(C)不起作用吗?

谢谢您的帮助。

1 个答案:

答案 0 :(得分:2)

您的(C)查询的问题是,对table2外部引用已完成不受约束 1 。这意味着您将有效地再次编写查询B,还需要将结果交叉联接写入table2,这意味着您将得到的不是2个结果,而是20000个。

您应该使用显式联接语法。这样做的优点之一是,它迫使您在连接时考虑连接条件 ,而不必记住将它们包含在常规where子句中。

select t1.*, t2.*
from table1 t1
inner join table2 t2 
on t1.item = t2.item 
and t1.something = t2.something

省略on子句是错误。忘记约束where子句 2 中的列永远不会出错。


1 只是因为您在table2子查询中再次引用了exists,即使您为其分配了相同的t2别名,也不会表示它们是相同引用。对table2的两个引用在任何方面都是无关的。

2 当然,执行此操作通常是逻辑错误,但是我在本段中的意思是有关系统将引发的错误消息。