Таблица псевдонимов в SQL Server и использование существующих - PullRequest
0 голосов
/ 14 декабря 2018

Я пытаюсь точно понять, как работает Exists, поэтому я сделал эту быструю временную таблицу, чтобы попытаться обернуть вокруг нее голову.

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

Когда я используюполное имя таблицы в верхнем запросе для ссылки на имя столбца в существующем операторе, с которым я сопоставляюсь, я получаю ожидаемые результаты.

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')

Results (Correct):

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

Так что утверждение о существовании сбивается с толку и думает, что оно соответствует num из #mytesttable для себя.То есть, выглядит ли это следующим образом:

#mytesttable inner join #mytesttable
on num = num

И как только оно оценивается как True, оно даже не смотрит на предложение Where?Если бы кто-то мог пролить свет на это, это было бы здорово.

1 Ответ

0 голосов
/ 14 декабря 2018

Это относится к области видимости / видимости столбца:

Подзапросы

Общее правило заключается в том, что имена столбцов в выражении неявноквалифицируется таблицей, указанной в предложении FROM на том же уровне. Если в таблице, на которую есть ссылка в предложении FROM подзапроса, не существует столбца, он неявно определяется таблицей, указанной в предложении FROM внешнегоquery.

Итак, ваш первый запрос имеет соединение:

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

Я предлагаю следовать принципу EIBTI («Явный лучше, чем неявный») и явноквалифицировать все столбцы псевдонимами таблиц.

...