Задавая другой вопрос , я обнаружил, что SQL Server (случается как в 2005, так и в 2008 году), похоже, имеет странное противоречивое поведение при работе с операторами CASE
в предложениях оконных функций.Следующий код выдает ошибку:
declare @t table (SortColumn int)
insert @t values (1), (2), (3)
declare @asc bit
set @asc = 0
select row_number() over (order by
case when 1=1 then SortColumn end asc,
case when 1=0 then SortColumn end desc) RowNumber
, *
from @t
Ошибка: Оконные функции не поддерживают константы как выражения предложения ORDER BY. Я полагаю, это потому, что оператор case
может вычислить какNULL
, который является константой.Как и следовало ожидать, этот код выдает ту же ошибку:
declare @t table (SortColumn int)
insert @t values (1), (2), (3)
declare @asc bit
set @asc = 0
select row_number() over (order by
NULL asc,
NULL desc) RowNumber
, *
from @t
... предположительно по той же причине.Однако этот код не выдает ошибку:
declare @t table (SortColumn int)
insert @t values (1), (2), (3)
declare @asc bit
set @asc = 0
select row_number() over (order by
case when @asc=1 then SortColumn end asc,
case when @asc=0 then SortColumn end desc) RowNumber
, *
from @t
Единственное отличие здесь от первого кодового блока состоит в том, что я переместил один из условных операндов case
операторов в переменную @asc
.Теперь это работает отлично.Но почему?Операторы case
могут по-прежнему принимать значение NULL
, которое является константой, поэтому оно не должно работать ... но оно работает.Это как-то согласуется или это особый случай, введенный Microsoft?
Все это можно проверить, поиграв с этим запросом .
Обновление: Это ограничение относится не только к предложениям OVER
(хотя они дают другую ошибку) - оно применяется ко всем предложениям ORDER BY
начиная с SQL Server 2005. Вот запрос , который также показывает ограничение с помощью регулярного предложения SELECT
* ORDER BY
.