EXCEPT
обрабатывает NULL
значения как сопоставимые.
Этот запрос:
WITH q (value) AS
(
SELECT NULL
UNION ALL
SELECT 1
),
p (value) AS
(
SELECT NULL
UNION ALL
SELECT 2
)
SELECT *
FROM q
WHERE value NOT IN
(
SELECT value
FROM p
)
вернет пустой набор строк.
Этот запрос:
WITH q (value) AS
(
SELECT NULL
UNION ALL
SELECT 1
),
p (value) AS
(
SELECT NULL
UNION ALL
SELECT 2
)
SELECT *
FROM q
WHERE NOT EXISTS
(
SELECT NULL
FROM p
WHERE p.value = q.value
)
вернет
NULL
1
, а этот:
WITH q (value) AS
(
SELECT NULL
UNION ALL
SELECT 1
),
p (value) AS
(
SELECT NULL
UNION ALL
SELECT 2
)
SELECT *
FROM q
EXCEPT
SELECT *
FROM p
вернет:
1
Рекурсивная ссылка также разрешена в предложении EXCEPT
в рекурсивном CTE
, хотя ведет себя странно способ: он возвращает все, кроме последней строки предыдущего набора, не все, кроме всего предыдущего набора:
WITH q (value) AS
(
SELECT 1
UNION ALL
SELECT 2
UNION ALL
SELECT 3
),
rec (value) AS
(
SELECT value
FROM q
UNION ALL
SELECT *
FROM (
SELECT value
FROM q
EXCEPT
SELECT value
FROM rec
) q2
)
SELECT TOP 10 *
FROM rec
---
1
2
3
-- original set
1
2
-- everything except the last row of the previous set, that is 3
1
3
-- everything except the last row of the previous set, that is 2
1
2
-- everything except the last row of the previous set, that is 3, etc.
1
Разработчики SQL Server
, должно быть, просто забыли запретить это.
EXCEPT сравнивает все (парные) столбцы двух полных выборок. NOT EXISTS сравнивает две или более таблиц в соответствии с условиями, указанными в предложении WHERE в подзапросе, следующем за ключевым словом NOT EXISTS.
EXCEPT можно переписать, используя NOT EXISTS. (КРОМЕ ВСЕХ можно переписать, используя ROW_NUMBER и НЕ СУЩЕСТВУЕТ.)
Получено из здесь
Планы выполнения SQL-сервера не учитываются. При возникновении проблем с производительностью я всегда обнаруживал, что это было совершенно произвольно (с точки зрения пользователя, я уверен, что авторы алгоритмов поймут почему), когда один синтаксис дает лучший план выполнения, чем другой.
В этом случае что-то о сравнении параметров запроса позволяет SQL определить ярлык, который он не может использовать с помощью прямого оператора выбора. Я уверен, что это недоработка алгоритма. Другими словами, вы можете логически интерполировать то же самое, но алгоритм не выполняет такой перевод в существующем запросе. Иногда это происходит потому, что алгоритм, который мог бы надежно вычислить это, потребует больше времени для выполнения, чем сам запрос, или, по крайней мере, так считал разработчик алгоритма.
Я уверен, что разработчики алгоритмов поймут, почему, когда один синтаксис дает лучший план выполнения, чем другой.В этом случае что-то в сравнении параметров запроса позволяет SQL определить ярлык, который он не мог бы получить при прямом выборе заявление. Я уверен, что это недоработка алгоритма. Другими словами, вы можете логически интерполировать то же самое, но алгоритм не выполняет такой перевод в существующем запросе. Иногда это происходит потому, что алгоритм, который мог бы надежно вычислить это, потребует больше времени для выполнения, чем сам запрос, или, по крайней мере, так считал разработчик алгоритма.
Я уверен, что разработчики алгоритмов поймут, почему, когда один синтаксис дает лучший план выполнения, чем другой.В этом случае что-то в сравнении параметров запроса позволяет SQL определить ярлык, который он не мог бы получить при прямом выборе заявление. Я уверен, что это недоработка алгоритма. Другими словами, вы можете логически интерполировать то же самое, но алгоритм не выполняет такой перевод в существующем запросе. Иногда это происходит потому, что алгоритм, который мог бы надежно вычислить это, потребует больше времени для выполнения, чем сам запрос, или, по крайней мере, так считал разработчик алгоритма.
что-то в сравнении параметров запроса позволяет SQL определить ярлык, который не может быть получен с помощью прямого оператора select. Я уверен, что это недоработка алгоритма. Другими словами, вы можете логически интерполировать то же самое, но алгоритм не выполняет такой перевод в существующем запросе. Иногда это происходит потому, что алгоритм, который мог бы надежно вычислить это, потребует больше времени для выполнения, чем сам запрос, или, по крайней мере, так считал разработчик алгоритма. что-то в сравнении параметров запроса позволяет SQL определить ярлык, который не может быть получен с помощью прямого оператора select. Я уверен, что это недоработка алгоритма. Другими словами, вы можете логически интерполировать то же самое, но алгоритм не выполняет такой перевод в существующем запросе. Иногда это происходит потому, что алгоритм, который мог бы надежно вычислить это, потребует больше времени для выполнения, чем сам запрос, или, по крайней мере, так считал разработчик алгоритма.