在 SQL 服务器中为 Table 添加别名并使用 Exists

Aliasing Table in SQL Server and Using Exists

我试图准确理解 Exists 是如何工作的,所以我做了这个快速临时 table 来尝试让我的头脑围绕它。

Drop Table #mytesttable
create table #mytesttable (edate date, num decimal(4,0), stat varchar(8),etype varchar(12))
insert into #mytesttable 
values ('20180401',1,'E','A/W'),
('20180101',1,'E','A/W'),
('20180701',1,'E','A/W'),
('20181001',1,'E','A/W'),
('20190101',1,'E','A'),
('20190301',1,'I','NULL'),
('20190101',2,'E','A'),
('20190301',2,'E','A'),
('20180901',2,'E','A'),
('20190101',3,'E','NULL'),
('20190301',3,'I','NULL'),
('20180901',3,'I','NULL')

当执行下面的查询时,我得到了三行,而我预计只有 1 行。

Select *
From #mytesttable
Where edate = '20190101'
and stat = 'E'
and exists(Select *
From #mytesttable sub
Where  sub.num = num
and sub.etype  = 'A/W'
and sub.edate < '20190101')

结果:

edate   num stat    etype
2019-01-01  1   E   A
2019-01-01  2   E   A
2019-01-01  3   E   NULL

当我在顶部查询中使用 table 的全名来引用我正在匹配的存在语句中的列名时,我得到了我期望的结果。

Select *
From #mytesttable
Where edate = '20190101'
and stat = 'E'
and exists(Select *
From #mytesttable sub
Where  sub.num = #mytesttable.num
and sub.etype  = 'A/W'
and sub.edate < '20190101')

结果(正确):

edate   num stat    etype
2019-01-01  1   E   A

exists 语句也因此感到困惑,并认为它正在将 #mytesttable 中的 num 与其自身相匹配。也就是说,是不是把这个看成:

#mytesttable inner join #mytesttable
on num = num

一旦计算结果为 True,它甚至都不查看 Where 子句?如果有人能阐明这一点,那就太棒了。

与第scope/visibility列相关:

Subqueries

The general rule is that column names in a statement are implicitly qualified by the table referenced in the FROM clause at the same level. If a column does not exist in the table referenced in the FROM clause of a subquery, it is implicitly qualified by the table referenced in the FROM clause of the outer query.

所以你的第一个查询有连接:

From #mytesttable sub
Where  sub.num = num
<=>
FROM #mytesttable sub
WHERE sub.num = sub.num   --always true for NOT NULL column

我建议遵循 EIBTI('Explicit Is Better Than Implicit') 原则,并使用 table 别名明确限定所有列。