在 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列相关:
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 别名明确限定所有列。
我试图准确理解 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列相关:
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 别名明确限定所有列。