首页 新闻 会员 周边 捐助

sql server查询为什么不报错

0
悬赏园豆:10 [待解决问题]

create table #a(
F1 int ,
F2 int,
F3 int,
F4 int
)
insert into #a
select 1,2,3,4 union all
select 2,2,3,4 union all
select 3,2,3,4 union all
select 4,2,3,4 union all
select 5,2,3,4

create table #b(
F1 int ,
F2 int
)
insert into #b
select 2,1 union all
select 3,1 union all
select 4,1

select * from #a
select * from #b

select * from #a where F1 in (select F3 from #b)

dunkS的主页 dunkS | 菜鸟二级 | 园豆:382
提问于:2022-09-30 08:41
< >
分享
所有回答(8)
0

为什么要报错呢?

xiongacv | 园豆:90 (初学一级) | 2022-09-30 09:20

select F3 from #b 表中并没有F3字段

支持(0) 反对(0) dunkS | 园豆:382 (菜鸟二级) | 2022-09-30 09:28
0

个人觉得 这里F3是属于一个常数了,取的是a表当前行的F3字段的值,也就是这个查询等价于查找a表F1和F3值相等的行

人之为言 | 园豆:207 (菜鸟二级) | 2022-09-30 09:41

这样的化,就很难发现代码的错误了

支持(0) 反对(0) dunkS | 园豆:382 (菜鸟二级) | 2022-09-30 09:43

@dunkS: sql server我不太熟,但是这里如果指定表名的话,应该是会报错的。我用Mysql一般做类似查询的时候,我喜欢把外表和内表都起上别名,取字段的时候就是 别名.字段名,这样就会清晰很多,也可以避免上面的问题。

支持(0) 反对(0) 人之为言 | 园豆:207 (菜鸟二级) | 2022-09-30 09:47
0

Create table #b(
F1 int,
F2 int,
F3 int
)
你创建表的时候本来就没添加F3字段吧

但乱红尘熊 | 园豆:773 (小虾三级) | 2022-09-30 09:41

你再仔细看看,没有F3

支持(0) 反对(0) dunkS | 园豆:382 (菜鸟二级) | 2022-09-30 09:42

@dunkS: 是的,没有,所以会报错吧,select F3 from #b,不是査的#b表里的字段吗

支持(0) 反对(0) 但乱红尘熊 | 园豆:773 (小虾三级) | 2022-09-30 09:46

@气氛组(红尘熊): 没报错

支持(0) 反对(0) dunkS | 园豆:382 (菜鸟二级) | 2022-09-30 09:48

@dunkS: 应该是没有从属的事,F3因为#b没有,而你前面也查询了#a,就默认了F3是#a的,并复给了select F3 from #b这次查询的结果,所以就类似select * from #a where F1=F3

支持(0) 反对(0) 但乱红尘熊 | 园豆:773 (小虾三级) | 2022-09-30 10:13
0

你这字段不加属主,应该报错,应该f1和f3都是常量而非字段?

With_Lilith | 园豆:362 (菜鸟二级) | 2022-09-30 09:45
0

能复现,f1到f4都不错,f5报错了。如果在#a里加了字段f5,那么f5也不报错了

会长 | 园豆:12463 (专家六级) | 2022-09-30 10:05
0

找到答案了
https://learn.microsoft.com/zh-cn/sql/relational-databases/performance/subqueries?view=sql-server-2017#qualifying
如果某个子查询中引用的列不存在于该子查询的 FROM 子句引用的表中,而存在于外部查询的 FROM 子句引用的表中,则该查询可以正确执行。 SQL Server使用外部查询中的表名称隐式限定子查询中的列。

新* | 园豆:271 (菜鸟二级) | 2022-09-30 10:24

有点迷糊,那这样的话,子查询的返回结果这么得到呢。用了这么多年SQL server,居然不知道还要这个规则......

支持(0) 反对(0) 会长 | 园豆:12463 (专家六级) | 2022-09-30 10:57

@会长: 子查询并不能单独执行的,根据sqlserver的规则,在子查询中是把#b隐式用#a替换了

支持(0) 反对(0) 新* | 园豆:271 (菜鸟二级) | 2022-09-30 11:21

@十一年新: 彩

支持(0) 反对(0) 会长 | 园豆:12463 (专家六级) | 2022-09-30 12:57
0

这里的F3 其实是 #a 表的 F3 所以不会报错的
sql 改成

select * from #a where F1 in (select #b.F3 from #b)

就报错了

Tom.汤 | 园豆:3058 (老鸟四级) | 2022-09-30 10:47
0

这是因为再查询的时候先是查找#b是否有F3字段 如果没有就在a#的表去找 此时再找不到才报错
select * from #a where F1 in (select F3 from #b) 这个查询语句如果#b没有字段F3 这时可以把查询语句理解为
select * from #a where F1 in (F3) 此时#b表是没有任何用处的

lf03 | 园豆:549 (小虾三级) | 2022-10-18 17:48
清除回答草稿
   您需要登录以后才能回答,未注册用户请先注册