SQL Server: оператор WHERE и псевдонимы столбцов
Содержание:
1. WHERE для фильтрации, ON для сопоставления;
2. Аргументы поиска и равенство против отличия. Часть I;
3. Аргументы поиска и равенство против отличия. Часть II;
4. Аргументы поиска и равенство против отличия. Часть III;
5. Укороченная операция;
6. WHERE и псевдонимы столбцов (Вы читаете данный раздел).
Пользователи часто стремятся использовать псевдонимы столбцов, созданных в списке SELECT для столбцов, ставших результатом вычислений в операторе WHERE, как в листинге ниже.
Однако помните, что при логической обработке запросов оператор WHERE (шаг 2) вычисляется перед оператором SELECT (шаг 5). Следовательно, псевдонимы, созданные в операторе SELECT невидимы для выражений в операторе WHERE. Этот программный код приводит к ошибкам, как на экране выше. Причина, по которой выдаются три ошибки, состоит в том, что custlocation предиката IN (N’Spain. Madrid’, N’France. Paris’, N’USA. WA. Seattle’) внутренне преобразуется в соединение трех предикатов: custlocation = N’Spain.Madrid’ OR custlocation = N’France.Paris’ OR custlocation = N’USA.WA. Seattle’.
Очевидный обходной прием — использовать табличное выражение, такое как CTE или производная таблица. Вы создаете псевдоним во внутреннем запросе и используете его везде, где нужно, во внешнем запросе. Более изящное решение — объединить оператор APPLY с оператором VALUES (конструктор значений таблицы) и таким образом создать псевдонимы, необходимые на очень ранних этапах логической обработки, как часть обработки оператора FROM. В результате псевдонимы будут доступны операторам, вычисляемым на последующих этапах, таким как оператор WHERE. Программный код для нашего примера выглядит так, как показано в листинге ниже.
На первый взгляд оператор WHERE — всего лишь простой фильтр, и не может быть предметом пристального внимания. Но, как выясняется, это гораздо более сложная тема. Логическая обработка запросов объясняет, почему нельзя ссылаться на псевдонимы, которые были определены в операторе SELECT, в операторе WHERE и почему не гарантирован порядок вычисления выражений в операторе WHERE. Также необходимо учитывать сложности, связанные с обработкой значений NULL, в частности различия между сравнениями на основе равенства и отличия.
Глубокое понимание этой темы поможет составить корректный и надежный программный код. Кроме того, важно понять особенности физической обработки запросов, например какие формы предикатов составляют аргумент поиска, а какие нет, чтобы иметь возможность строить оптимальные запросы.
1. WHERE для фильтрации, ON для сопоставления;
2. Аргументы поиска и равенство против отличия. Часть I;
3. Аргументы поиска и равенство против отличия. Часть II;
4. Аргументы поиска и равенство против отличия. Часть III;
5. Укороченная операция;
6.
Пользователи часто стремятся использовать псевдонимы столбцов, созданных в списке SELECT для столбцов, ставших результатом вычислений в операторе WHERE, как в листинге ниже.
Однако помните, что при логической обработке запросов оператор WHERE (шаг 2) вычисляется перед оператором SELECT (шаг 5). Следовательно, псевдонимы, созданные в операторе SELECT невидимы для выражений в операторе WHERE. Этот программный код приводит к ошибкам, как на экране выше. Причина, по которой выдаются три ошибки, состоит в том, что custlocation предиката IN (N’Spain. Madrid’, N’France. Paris’, N’USA. WA. Seattle’) внутренне преобразуется в соединение трех предикатов: custlocation = N’Spain.Madrid’ OR custlocation = N’France.Paris’ OR custlocation = N’USA.WA. Seattle’.
Очевидный обходной прием — использовать табличное выражение, такое как CTE или производная таблица. Вы создаете псевдоним во внутреннем запросе и используете его везде, где нужно, во внешнем запросе. Более изящное решение — объединить оператор APPLY с оператором VALUES (конструктор значений таблицы) и таким образом создать псевдонимы, необходимые на очень ранних этапах логической обработки, как часть обработки оператора FROM. В результате псевдонимы будут доступны операторам, вычисляемым на последующих этапах, таким как оператор WHERE. Программный код для нашего примера выглядит так, как показано в листинге ниже.
Обманчивая простота WHERE
На первый взгляд оператор WHERE — всего лишь простой фильтр, и не может быть предметом пристального внимания. Но, как выясняется, это гораздо более сложная тема. Логическая обработка запросов объясняет, почему нельзя ссылаться на псевдонимы, которые были определены в операторе SELECT, в операторе WHERE и почему не гарантирован порядок вычисления выражений в операторе WHERE. Также необходимо учитывать сложности, связанные с обработкой значений NULL, в частности различия между сравнениями на основе равенства и отличия.
Глубокое понимание этой темы поможет составить корректный и надежный программный код. Кроме того, важно понять особенности физической обработки запросов, например какие формы предикатов составляют аргумент поиска, а какие нет, чтобы иметь возможность строить оптимальные запросы.