#sql-server
#sql-сервер
Вопрос:
У меня вопрос о Any-Operator .
В Technet говорится
Например, следующий запрос находит клиентов, расположенных на территории, не охваченной никакими продавцами.
Use AdventureWorks2008R2;
GO
SELECT
CustomerID
FROM
Sales.Customer
WHERE
TerritoryID <> ANY
(
SELECT
TerritoryID
FROM
Sales.SalesPerson
);
Далее
Результаты включают всех клиентов, кроме тех, чьи территории продаж равны НУЛЮ, поскольку каждая территория, назначенная клиенту, покрывается продавцом. Внутренний запрос находит все территории продаж, охваченные продавцами, а затем для каждой территории внешний запрос находит клиентов, которых нет ни на одной.
Но этот запрос возвращает всех клиентов. Я обновил идентификатор территории клиентов до значения, которого нет у sales.person, но все же этот запрос возвращает всех клиентов вместо того, которого я ожидал..
Я что-то упускаю? Может быть, эта статья о technet просто неверна? https://technet.microsoft.com/de-de/library/ms187074 (v=sql.105).aspx (немецкий)
Есть один клиент с TerritoryID = 13
Результат внутреннего запроса (ВЫБЕРИТЕ TerritoryID ИЗ Sales.Продавец) : 4 2 4 3 6 5 1 4 6 1 1 6 9 1 8 10 7
И в таблице продаж.Customer — это строка с CustomerID = 13, которая не охвачена продавцом..
Комментарии:
1. Английская версия ( technet.microsoft.com/en-US/library/ms187074 (v = sql.105).aspx ) — который, как мы можем предположить, является каноническим, гласит (со ссылкой на опубликованный вами код): «Результаты включают всех клиентов, кроме тех, чьи территории продаж равны НУЛЮ, потому что каждая территория, назначенная клиенту, покрытаспециалистом по продажам.» — вы уверены, что ваш запрос возвращает каждого клиента или просто клиента с очень ненулевой территорией? Помните, что операторы сравнения не работают интуитивно со
NULL
значениями.2. У вас не равно НИ ОДНОЙ строке. проще говоря, если в SalesPerson есть хотя бы 2 строки, вы получите все строки обратно. потому что одно значение может совпадать, а другое — нет. 🙂 Для чего-то подобного, чтобы найти дубликаты, я бы предпочел использовать левое соединение или exists .
3. » вы уверены, что ваш запрос возвращает каждого клиента» — да.
4. в нем говорится: «Внутренний запрос находит все территории продаж, охваченные продавцами, а затем для каждой территории внешний запрос находит клиентов, которых нет в одном» — и этот внешний запрос показывает каждого клиента (но у них есть covered TerritoryID .. и это то, что я не понимаю
Ответ №1:
create table #t1
(
id int
)
insert into #t1
values(1),(2),(3)
Как вы можете видеть, T1 имеет три значения
теперь давайте посмотрим, как работает Any
Когда ‘равно ‘ используется с любым, это работает как В
select * from #t1 where id=
any(select 0)--no result
когда Any
используется с > или <> , Any
означает получение всех значений, которые больше минимального значения
select * from #t1 where id<>
any(select 1)--2,3
select * from #t1 where id<>
any(select 0)--1,2,3
Если ваш подзапрос возвращает одно значение, внешний запрос попытается получить значения, которые больше, чем внутренний запрос
Комментарии:
1. Я понимаю ваш пример 🙂 Но я не понимаю, что в нем говорится: «Например, следующий запрос находит клиентов, расположенных на территории, не охваченной никакими продавцами.». . technet.microsoft.com/en-us/library/ms187074 (v=sql.105).aspx
2. . у меня нет этой конкретной базы данных для тестирования. пожалуйста, обновите qstn с помощью результата внутреннего запроса
Ответ №2:
<> ANY
означает любые продажи.Клиент с идентификатором территории, который больше или меньше любого из идентификаторов территории в Sales.SalesPerson
so TerritoryID = 13
больше, чем все или ваши примеры (4 2 4 3 6 5 1 4 6 1 1 6 9 1 8 10 7)
, поэтому он включен.
<> ALL
это эквивалент NOT IN
so, с которым вы путаете <> ANY
Посмотрите на <> ANY
as, если в наборе есть какие-либо записи, которые не равны параметру quailifier, затем включите его.
Ответ №3:
Следующий запрос имеет тот же результат:
SELECT CustomerID FROM Sales.Customer
WHERE TerritoryID NOT IN (SELECT TerritoryID FROM Sales.SalesPerson)
Комментарии:
1. OP пытается понять, почему его оператор ведет себя определенным образом — это не помогает ответить на этот вопрос.