为什么要在LEFT JOIN子句中使用一个字段,然后在WHERE子句中再进行过滤呢?

9 浏览
0 Comments

为什么要在LEFT JOIN子句中使用一个字段,然后在WHERE子句中再进行过滤呢?

查询

SELECT ID, Name, Phone 
FROM Table1 
LEFT JOIN Table2 ON Table1.ID = Table2.ID
WHERE Table2.ID IS NULL

问题

  • 很难理解为什么有人会在ID上进行左连接,然后在where子句中将其设置为NULL?
  • 我是否遗漏了什么?这样做有什么重要性吗?
  • 我们可不可以完全省略Table2?即根本不进行连接?

非常感谢任何帮助。

0
0 Comments

为什么会在LEFT JOIN的字段上进行过滤,然后在WHERE子句中将其排除?

在关系数据库中,这是实现反连接(antijoin)的一种方式,被SQL Server术语称为反半连接(anti semi join)。它的本质是“从一个表中获取不在另一个表中的行”。

我能想到的几种实现方式有:

select cols from t1 left join t2 on t1.key=t2.key where t2.key is null

select cols from t1 where key not in (select key from t2)

select cols from t1 where not exists (select 1 from t2 where t1.key=t2.key)

甚至可以使用以下方式:

select * from t1 where key in (select key from t1 except select key from t2)

这些方法之间存在一些差异(尤其是在使用not in时,空值处理的风险),但它们基本上都能实现相同的功能。

回答你的问题:

很难理解为什么有人会在ID上进行LEFT JOIN,然后在WHERE子句中将其设置为NULL?

正如前面提到的,为了排除在t2中存在的t1结果。

我们可以完全省略Table2吗?也就是说根本不进行连接?

如果不使用连接(或其任何等效的替代方法),你将获得更多的结果,因为与table2中的任何行具有相同ID的table1中的行也将被返回。

0
0 Comments

为什么会在LEFT JOIN的字段上进行LEFT JOIN,然后在WHERE子句中过滤它?

在上述问题中,LEFT JOIN被用于连接两个表,并获取所有没有电话号码的用户。然而,LEFT JOIN后的结果仍然包含了具有电话号码的用户。这种情况可能会导致问题,因为我们只想获取没有电话号码的用户。

这个问题的出现可能是因为在进行LEFT JOIN操作时,可能没有正确指定表的别名,导致在WHERE子句中无法正确过滤数据。为了解决这个问题,我们可以为每个表设置别名,并在查询中明确指定每个列来自哪个表。

解决方法如下所示:

SELECT t1.ID, t1.Name, t2.Phone
FROM Table1 AS t1
LEFT JOIN Table2 AS t2 ON t1.ID = t2.ID
WHERE t2.Phone IS NULL

通过为每个表设置别名,并在LEFT JOIN和WHERE子句中使用这些别名,我们可以正确地获取所有没有电话号码的用户。在这个解决方法中,我们使用t1和t2作为别名来代表Table1和Table2。

这样,我们就可以正确地使用WHERE子句来过滤出没有电话号码的用户,并避免了在LEFT JOIN字段上进行过滤时出现的问题。

0
0 Comments

为什么会在LEFT JOIN的字段上进行过滤然后在WHERE子句中进行过滤呢?

在这里提到的查询与以下查询基本上是等价的:

SELECT ID,Name,Phone

FROM Table1

WHERE NOT EXISTS

(SELECT 1

FROM Table2

WHERE Table1.ID = Table2.ID

意思是选择Table1中所有没有与Table2中的相关记录的记录。

这两个查询的执行计划很可能是相同的(个人而言,我从未见过它们产生不同执行计划的情况,但我不排除这种可能性),所以这两个查询的效率应该是相同的,而且由你来决定哪种语法更容易读懂,是使用LEFT JOIN还是使用exists语法。

0