В своем выпуске 2015 года T-SQL Querying Ицик Бен-Ган обновил обработку логического запроса в «СПИСОК 1-1 номера шагов логической обработки запроса» следующим образом:
(5) SELECT (5-2) DISTINCT (7) TOP(<top_specification>) (5-1) <select_list>
(1) FROM (1-J) <left_table> <join_type> JOIN <right_table> ON <on_predicate>
| (1-A) <left_table> <apply_type> APPLY <right_input_table> AS <alias>
| (1-P) <left_table> PIVOT(<pivot_specification>) AS <alias>
| (1-U) <left_table> UNPIVOT(<unpivot_specification>) AS <alias>
(2) WHERE <where_predicate>
(3) GROUP BY <group_by_specification>
(4) HAVING <having_predicate>
(6) ORDER BY <order_by_list>
(7) OFFSET <offset_specification> ROWS FETCH NEXT <fetch_specification> ROWS ONLY;
В отличие от предыдущей версии книги 2008 года, ORDER BY
(шаг 6
) теперь происходит до TOP
(шаг 7
).Конечно, как указано в другом месте, оба связаны.Как объясняет Ицик на 6 странице Запросы T-SQL :
[TOP] фильтрует указанное количество строк на основе порядка в предложении ORDER BY или на основе произвольногопорядок, если предложение ORDER BY отсутствует.С OFFSET-FETCH эта фаза пропускает указанное количество строк, а затем фильтрует следующее указанное количество строк на основе порядка в предложении ORDER BY.
Понимание вышеупомянутых шагов обработки логического запросаважно, потому что он объясняет иные неинтуитивные причуды в SQL.
Например, вы не можете использовать псевдоним из предложения SELECT
(шаг 5-2
) в предложении WHERE
(шаг 2
), потому что механизм выражений оценивает предложение WHERE
передSELECT
пункт.
-- This won't work!
SELECT Cost = Quantity * Price
FROM Orders
WHERE Cost > 500.00;
Как говорит Ицик в своей книге: «Фазы логической обработки запроса имеют определенный порядок. Напротив, оптимизатор часто может создавать ярлыки в физическом плане выполнения, который он генерирует.Конечно, он будет делать ярлыки, только если набор результатов гарантированно будет правильным. "