为啥当我的子查询无效时,此 SQL 查询会起作用? - 甲骨文 [重复]

Posted

技术标签:

【中文标题】为啥当我的子查询无效时,此 SQL 查询会起作用? - 甲骨文 [重复]【英文标题】:Why does this SQL query work when I have an invalid subquery? - Oracle [duplicate]为什么当我的子查询无效时,此 SQL 查询会起作用? - 甲骨文 [重复] 【发布时间】:2019-11-22 15:57:13 【问题描述】:

我在编写查询时犯了一个错误,我试图理解为什么这个查询甚至会运行。这是查询:

select * from user
where user_id in (select user_id from admin);

在此查询中,admin 表中没有字段user_id,但查询仍在运行,最终返回意外结果。在user 表中有一个user_id

当我将字段更改为主表中不存在的内容时,查询不会运行。

select * from user
where user_id in (select test_id from admin);

我也尝试用一个不存在的表来运行它,它也没有运行。

select * from user
where user_id in (select user_id from blah);

有人能解释一下为什么第一个查询有效吗?有没有更好的方法来编写这些更容易发现错误的查询?

【问题讨论】:

"有没有更好的方法来编写这些查询" - 是的,总是在列名前加上表别名 【参考方案1】:

总是限定您的列引用。你认为第一个查询是:

select u.*
from user u
where u.user_id in (select a.user_id from admin a);

因为a.user_id不存在,所以解释为:

select u.*
from user u
where u.user_id in (select u.user_id from admin a);

这是测试你可能不关心的两件事:

u.user_id 不为空 admin 至少有一行

【讨论】:

显然添加别名会有所帮助,但查询会运行仍然很奇怪。这也使得难以发现缺陷。为什么会在admin 中找到u.user_id @jhamm 。 . .这些是 SQL 的作用域规则。如果子查询中引用的列未被识别,则 SQL 将查找外部查询以获取引用。如果列是正确限定的(即包括表引用),它就不能这样做。

以上是关于为啥当我的子查询无效时,此 SQL 查询会起作用? - 甲骨文 [重复]的主要内容,如果未能解决你的问题,请参考以下文章

如果关系上没有索引,SQL 查询是不是会起作用?

为啥我的子查询谓词中的 LIKE[c] 与此名称不匹配?

为啥,当我在 WCF 服务中模拟时,当我尝试运行 LINQ to SQL 查询时,我的服务不能加载 System.Transactions?

SQL新建查询时,表名没错,为啥说对象名无效

无效的子查询但外部查询返回记录

为啥我的 PyMongo 查询中出现无效错误