LEFT JOIN右表为空查询不出数据

本文通过一个具体的例子展示了如何正确使用SQL的左连接(LEFT JOIN)与WHERE子句来获取所需的数据。错误的SQL语句会导致部分数据被误删,而正确的用法能够保留所有相关记录。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

表结构如下

表Table_A:
idname
1张三
2赵四
3王五
表Table_B:
idtype
11
22
33
想查询出A表中所有的结果并关联B中特定字段,如下表
idnametype
1张三1
2赵四null
3王五null
错误SQL:
SELECT A.* ,B.type FROM Table_A A LEFT JOIN Table_B B ON A.id=B.id WHERE B.type=1
结果:
idnametype
1张三1
正确SQL:
SELECT A.* ,B.type FROM Table_A A LEFT JOIN Table_B B ON A.id=B.id AND B.type=1
结果:
idnametype
1张三1
2赵四null
3王五null
原因:

sql1是在SELECT A.* ,B.type FROM Table_A A LEFT JOIN Table_B B ON A.id=B.id查询后执行WHERE B.type=1,所以过滤掉了type不为1的数据
sql2可以理解为是在A关联B时对比B进行了筛选

`NOT IN` 是 SQL 中用于筛选不在指定集合内的记录的关键字。如果你发现 `NOT IN` 查询条件无法返回预期的数据,可能是由于以下几个常见原因: ### 1. **子查询返回 NULL** 如果你在 `NOT IN` 子查询中返回了 `NULL` 值,则整个查询可能会导致没有结果返回。因为对于任何值来说,`value NOT IN (some_value, ..., NULL)` 的判断总是不确定的 (`UNKNOWN`),SQL 会将其视为假 (`FALSE`)。 **解决办法**:你可以通过确保子查询不会返回 `NULL` 或者显式排除 `NULL` 来避免这个问题。例如: ```sql SELECT * FROM table_name WHERE column_name NOT IN (SELECT sub_column_name FROM sub_table WHERE sub_column_name IS NOT NULL); ``` ### 2. **主和子查询数据类型不匹配** 确保主查询和子查询之间的列数据类型是一致的。如果两个字段的数据类型不同(如一个是字符串而另一个是整数),可能导致查询不出结果。 **解决办法**:检查并转换数据类型,使其一致。可以使用 `CAST()` 或其他类型的转换函数来进行处理。 ### 3. **索引或性能问题** 当涉及到大量的数据时,`NOT IN` 可能会导致性能问题,并且某些数据库优化器对 `NOT EXISTS` 达式的处理更为高效。因此,在大数据集上,`NOT IN` 性能较差也会影响结果返回的速度甚至失败。 **替代方案**:考虑改用 `LEFT JOIN ... IS NULL` 或 `NOT EXISTS` 这种更高效的语法结构。 - 使用 `LEFT JOIN ... IS NULL` 示例: ```sql SELECT t1.* FROM table_name AS t1 LEFT JOIN sub_table AS t2 ON t1.column_name = t2.sub_column_name WHERE t2.sub_column_name IS NULL; ``` - 使用 `NOT EXISTS` 示例: ```sql SELECT * FROM table_name AS t1 WHERE NOT EXISTS ( SELECT 1 FROM sub_table AS t2 WHERE t1.column_name = t2.sub_column_name ); ``` ### 4. **查询范围过大** 如果 `NOT IN` 后面跟的是一个非常大的列或者是全量扫描的结果集,那么这不仅影响效率还容易造成内存溢出等问题,最终使得查询无果而终。 --- 总结下来,排查 `NOT IN` 查不到数据的原因可以从以上几个方面入手:确认是否有 `NULL` 返回、数据类型是否匹配以及是否存在潜在的性能瓶颈等。
评论 14
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值