Полагаю, я всегда наивно полагал, что скалярные функции в части select SQL-запроса будут применяться только к строкам, которые соответствуют всем критериям предложения where.
Сегодня я отлаживал некоторый кодот продавца, и это предположение было оспорено.Единственная причина, по которой я могу думать об этом коде, заключается в том, что функция Substring () вызывается для данных, которые должны были быть отфильтрованы предложением WHERE.Но, похоже, что вызов подстроки применяется до того, как произойдет фильтрация, запрос не выполнен.Вот пример того, что я имею в виду.Допустим, у нас есть две таблицы, каждая из которых имеет 2 столбца и имеет 2 строки и 1 строку соответственно.Первый столбец в каждом является просто идентификатором.NAME - это просто строка, а NAME_LENGTH сообщает нам, сколько символов в имени имеет одинаковый идентификатор.Обратите внимание, что только имена с более чем одним символом имеют соответствующую строку в таблице LONG_NAMES.
NAMES: ID, NAME
1, "Peter"
2, "X"
LONG_NAMES: ID, NAME_LENGTH
1, 5
Если я хочу, чтобы запрос печатал каждое имя с обрезанными последними 3 буквами, я мог бы сначала попробовать что-то вродеэто (предполагая синтаксис SQL Server на данный момент):
SELECT substring(NAME,1,len(NAME)-3)
FROM NAMES;
Я скоро обнаружу, что это даст мне ошибку, потому что, когда он достигает "X", он попытается использовать отрицательное число для в подстрокепозвоните, и это не удастся.Мой поставщик решил решить эту проблему, отфильтровав строки, строки которых были слишком короткими для выполнения запроса len - 3.Он сделал это, присоединившись к другой таблице:
SELECT substring(NAMES.NAME,1,len(NAMES.NAME)-3)
FROM NAMES
INNER JOIN LONG_NAMES
ON NAMES.ID = LONG_NAMES.ID;
На первый взгляд этот запрос выглядит так, как будто он может работать.Условие соединения удалит все строки, поля NAME которых достаточно короткие для вызова подстроки.
Однако из того, что я могу наблюдать, SQL Server иногда пытается вычислить выражение подстроки для всего в таблицеи затем примените объединение для фильтрации строк.Это должно произойти таким образом?Есть ли документированный порядок операций, где я могу узнать, когда произойдут определенные вещи?Это специфично для конкретного движка базы данных или части стандарта SQL?Если бы я решил включить в свою таблицу NAMES какой-нибудь предикат для фильтрации коротких имен (например, len (NAME)> 3), может ли SQL Server также применить это после попытки применить подстроку?Если так, то кажется, что единственный безопасный способ сделать подстроку - заключить ее в конструкцию «случай, когда» в select?