Sql 为什么要在字段上留下JOIN,然后在WHERE子句中过滤掉它?

Sql 为什么要在字段上留下JOIN,然后在WHERE子句中过滤掉它?,sql,sql-server,tsql,left-join,where-clause,Sql,Sql Server,Tsql,Left Join,Where Clause,质疑 问题 发现很难理解为什么有人会用身份证离开join 然后在where子句中将其设置为NULL? 我是不是遗漏了什么?这有什么意义吗? 我们能把表2全部省略掉吗?就像根本不加入? 任何帮助都将不胜感激。您在问题中的查询基本上等同于以下查询: SELECT ID, Name, Phone FROM Table1 WHERE NOT EXISTS ( SELECT 1 FROM Table2 WHERE Table1.ID = Table2.ID ) 这意味着它

质疑

问题

发现很难理解为什么有人会用身份证离开join 然后在where子句中将其设置为NULL? 我是不是遗漏了什么?这有什么意义吗? 我们能把表2全部省略掉吗?就像根本不加入?
任何帮助都将不胜感激。

您在问题中的查询基本上等同于以下查询:

SELECT ID, Name, Phone 
FROM Table1 
WHERE NOT EXISTS
(
    SELECT 1
    FROM  Table2 
    WHERE Table1.ID = Table2.ID
)
这意味着它会选择表1中所有在表2中没有相关记录的记录


就个人而言,两个查询的执行计划很可能是相同的,我从未见过它们生成不同的执行计划的情况,但我不排除这一点,因此两个查询的效率应该相同,您可以自行决定是使用left join还是exists语法更易于阅读。

这是实现反连接的关系数据库操作的方法之一,在sql server术语中称为反半连接。这本质上是从一个表中获取不在另一个表中的行

我无法想到的方法是:

从t1左键选择cols,在t1上连接t2。key=t2.key,其中t2.key为null

从t1中选择列,其中键不在t2中选择键

从不存在的t1中选择cols从t2中选择1,其中t1.key=t2.key

甚至

从t1选择*键,其中键入从t1选择键,从t2选择键除外

这些方法之间存在一些差异,最明显的是,not in的情况下存在null处理的危险,但它们通常都是这样做的

针对您的观点:

发现很难理解为什么有人会用身份证离开join 然后在where子句中将其设置为NULL

如上所述,为了排除t2中存在的t1结果

我们能把表2全部省略掉吗?就像根本不加入


如果不使用联接或其任何等价替代项,您将获得更多结果,因为表1中的行与表2中的任何行具有相同的id,也将被返回。

如果联接条件列的id值为null,则根据我的理解,这是不好的数据库设计

根据您下面的查询。下面是可能的scnario where条款

我假设您的姓名和电话号码来自表2,然后您尝试查找ID为空的姓名和电话号码

若名称和电话号码来自表1,而表2只是有ID连接,并没有从表2中选择任何内容,那个么where子句就是完全浪费

挑选 身份证件 名称 电话 从…起 表1 左连接 表2 在…上 表1.ID=表2.ID 哪里 表2.ID为空


基本上在上述常见业务场景中,开发人员将where子句筛选条件放在左联接中,当来自右侧的任何值都具有非相关性数据且不需要成为数据集的一部分时,则将其筛选出来。

我认为您应该为表指定一个别名,并指定每列来自哪个表

假设Name来自表1,Phone来自表2,ID在两者中都是公共的,那么上面提到的左连接可能有助于获取所有没有电话号码的用户

表1 身份证名称 1约翰·史密斯 2无名氏

表2 身份证电话 20715550863

不带where子句的左Join 身份证号码电话 1约翰·史密斯 2无名氏0715550863

用where子句左连接 身份证号码电话
1 John Smith NULL

可能的重复项是查找不存在记录的不同方法。有时这种方法更有效。如果FK约束未强制执行或不存在,Is也是一种查找孤立记录的好方法。通常称为左反连接。我同意你的观点,OP-我不明白人们为什么这样做以及其他很多事情。佐哈尔对此解释得很好。
SELECT ID, Name, Phone 
FROM Table1 
WHERE NOT EXISTS
(
    SELECT 1
    FROM  Table2 
    WHERE Table1.ID = Table2.ID
)