Когда использовать EXCEPT вместо NOT EXISTS в Transact SQL?

37
задан OMG Ponies 3 November 2009 в 18:27
поделиться

3 ответа

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 , должно быть, просто забыли запретить это.

37
ответ дан 27 November 2019 в 03:47
поделиться

EXCEPT сравнивает все (парные) столбцы двух полных выборок. NOT EXISTS сравнивает две или более таблиц в соответствии с условиями, указанными в предложении WHERE в подзапросе, следующем за ключевым словом NOT EXISTS.

EXCEPT можно переписать, используя NOT EXISTS. (КРОМЕ ВСЕХ можно переписать, используя ROW_NUMBER и НЕ СУЩЕСТВУЕТ.)

Получено из здесь

3
ответ дан 27 November 2019 в 03:47
поделиться

Планы выполнения SQL-сервера не учитываются. При возникновении проблем с производительностью я всегда обнаруживал, что это было совершенно произвольно (с точки зрения пользователя, я уверен, что авторы алгоритмов поймут почему), когда один синтаксис дает лучший план выполнения, чем другой.

В этом случае что-то о сравнении параметров запроса позволяет SQL определить ярлык, который он не может использовать с помощью прямого оператора выбора. Я уверен, что это недоработка алгоритма. Другими словами, вы можете логически интерполировать то же самое, но алгоритм не выполняет такой перевод в существующем запросе. Иногда это происходит потому, что алгоритм, который мог бы надежно вычислить это, потребует больше времени для выполнения, чем сам запрос, или, по крайней мере, так считал разработчик алгоритма.

Я уверен, что разработчики алгоритмов поймут, почему, когда один синтаксис дает лучший план выполнения, чем другой.

В этом случае что-то в сравнении параметров запроса позволяет SQL определить ярлык, который он не мог бы получить при прямом выборе заявление. Я уверен, что это недоработка алгоритма. Другими словами, вы можете логически интерполировать то же самое, но алгоритм не выполняет такой перевод в существующем запросе. Иногда это происходит потому, что алгоритм, который мог бы надежно вычислить это, потребует больше времени для выполнения, чем сам запрос, или, по крайней мере, так считал разработчик алгоритма.

Я уверен, что разработчики алгоритмов поймут, почему, когда один синтаксис дает лучший план выполнения, чем другой.

В этом случае что-то в сравнении параметров запроса позволяет SQL определить ярлык, который он не мог бы получить при прямом выборе заявление. Я уверен, что это недоработка алгоритма. Другими словами, вы можете логически интерполировать то же самое, но алгоритм не выполняет такой перевод в существующем запросе. Иногда это происходит потому, что алгоритм, который мог бы надежно вычислить это, потребует больше времени для выполнения, чем сам запрос, или, по крайней мере, так считал разработчик алгоритма.

что-то в сравнении параметров запроса позволяет SQL определить ярлык, который не может быть получен с помощью прямого оператора select. Я уверен, что это недоработка алгоритма. Другими словами, вы можете логически интерполировать то же самое, но алгоритм не выполняет такой перевод в существующем запросе. Иногда это происходит потому, что алгоритм, который мог бы надежно вычислить это, потребует больше времени для выполнения, чем сам запрос, или, по крайней мере, так считал разработчик алгоритма.

что-то в сравнении параметров запроса позволяет SQL определить ярлык, который не может быть получен с помощью прямого оператора select. Я уверен, что это недоработка алгоритма. Другими словами, вы можете логически интерполировать то же самое, но алгоритм не выполняет такой перевод в существующем запросе. Иногда это происходит потому, что алгоритм, который мог бы надежно вычислить это, потребует больше времени для выполнения, чем сам запрос, или, по крайней мере, так считал разработчик алгоритма.

2
ответ дан 27 November 2019 в 03:47
поделиться
Другие вопросы по тегам:

Похожие вопросы: