Функция ROW_NUMBER() возвращает значение varchar вместо int

Я использую функцию ROW_NUMBER() в SQL Server для создания нового столбца с именем RowNumber.

Но когда я позже в том же запросе ссылаюсь на это новое поле в операторе WHERE, я получаю эту ошибку, хотя поле должно быть целым числом:

Ошибка преобразования при преобразовании значения varchar 'RowNumber' в тип данных int

Вот мой запрос:

SELECT 
   ROW_NUMBER() OVER(PARTITION BY c.Node_base ORDER BY sum(c.Score) DESC) AS "RowNumber",  
   c.Node_base, c.Node_forslag, sum(Score)
FROM         
   t_input as c
WHERE 'RowNumber' < 11
GROUP BY c.Node_base, c.Node_forslag
ORDER BY c.Node_base desc

person MOLAP    schedule 28.06.2012    source источник
comment
Неправильный диагноз. Он не может преобразовать строку 'RowNumber' в строке 6. Это не имя поля, это просто строка. С таким же успехом можно сказать WHERE 'ThisIsAString' < 11. И поскольку < требует, чтобы оба значения были одного типа, он пытается преобразовать строку в INT и терпит неудачу.   -  person MatBailie    schedule 28.06.2012
comment
«Это строковый литерал». Это идентификатор в кавычках. Обратите внимание на разницу.   -  person underscore_d    schedule 16.07.2015


Ответы (4)


Вы не можете ссылаться на вычисляемый столбец из предложения SELECT в предложении WHERE, и даже если бы вы могли, одинарные кавычки вводят строковый литерал, а не ссылку на столбец. Используйте CTE или подзапрос.

;With Sums as (
    SELECT c.Node_base, c.Node_forslag,SUM(c.Score) as TotScore
    FROM t_input as c
    GROUP BY c.Node_base, c.Node_forslag
), NumberedRows as (
   SELECT *,ROW_NUMBER() OVER(PARTITION BY Node_base ORDER BY TotScore DESC) AS RowNumber
   FROM Sums
)
select * from NumberedRows
WHERE RowNumber <11
order by Node_base desc

Имя RowNumber вообще не нужно заключать в кавычки — это не зарезервированное слово и оно не содержит специальных символов.

person Damien_The_Unbeliever    schedule 28.06.2012
comment
Должен ли я вместо этого поместить его в предложение HAVING? - person MOLAP; 28.06.2012
comment
@MOLAP - Нет, вы также не можете ссылаться на него из HAVING. - person Damien_The_Unbeliever; 28.06.2012
comment
@MOLAP - я обновил запрос - я действительно не читал, что вы пытались сделать внутри ROW_NUMBER, я думаю, что теперь я приспособил его к тому, что вы хотели. - person Damien_The_Unbeliever; 28.06.2012
comment
Хорошо, спасибо. В итоге я использовал подзапрос, говорящий: Select * from (мой запрос без оператора ORDER BY) as d WHERE where RowNumber ‹11 order by d.Node_base desc - person MOLAP; 28.06.2012

В заявлении

WHERE 'RowNumber' <11

Вы сравниваете строковый литерал «RowNumber» с числом 11.

Просто уберите кавычки:

WHERE RowNumber <11
person Jon Egerton    schedule 28.06.2012
comment
Это приводит к: Недопустимому имени столбца «RowNumber». - person MOLAP; 28.06.2012
comment
@MOLAP: вы не можете ссылаться на столбец, который вы только что определили в SELECT внутри того же уровня WHERE - вам нужно обернуть этот оператор, который определяет RowNumber, в подзапрос или CTE. - person marc_s; 28.06.2012
comment
Да - применить фильтр так не получится. Как говорит @Damien_The_Unbeliever. (Предполагал, что вы обнаружите это и попытаетесь исправить это самостоятельно, когда получите ошибку - я стараюсь не слишком много кормить с ложки). - person Jon Egerton; 28.06.2012

Используйте [RowNumber] вместо "RowNumber".

Если параметр SET QUOTED_IDENTIFIER включен (по умолчанию), все строки заключаются в двойные кавычки. метки интерпретируются как идентификаторы объектов.

Вам также придется использовать подзапрос для ссылки на row_number() в предложении where, например:

select  ...
from    (
        SELECT  ROW_NUMBER() OVER(PARTITION BY Node_base 
                    ORDER BY sum(Score) DESC) AS RowNumber
        ,       ...
        from    t_input
        ) as SubQueryAlias
where   RowNumber < 11

Или в вашем случае, я думаю, вы можете просто использовать top:

select  top 11 Node_base
,       Node_forslag
,       sum(Score)
from    t_input
group by
        Node_base
,       Node_forslag
order by
        sum(Score) desc
person Andomar    schedule 28.06.2012
comment
Не думаете, что Top будет работать, это вернет первые 11 строк, а не первые 11 строк для каждого раздела? - person Jon Egerton; 28.06.2012
comment
Я только что проверил функцию TOP, и в этом случае она не будет работать. - person MOLAP; 28.06.2012
comment
@JonEgerton: Да, top вернет 11 лучших (base, forslag) групп. Вариант row_number() делает что-то странное: первые 11 групп (base) группируются по (base, forslag). Не уверен, что это то, что нужно ОП. - person Andomar; 28.06.2012
comment
Часть 1 этого ответа может заставить его работать. (используйте подзапрос, чтобы обратиться к новому полю RowNumber. - person MOLAP; 28.06.2012
comment
Разве не для этого было изобретено CROSS APPLY? - person underscore_d; 16.07.2015

выберите row_number() (упорядочить по c.Node_base) как RowNumber, c.Node_base, c.Node_forslag, sum(Score)

ОТ t_input как c

ГДЕ 'RowNumber' ‹ 11

СГРУППИРОВАТЬ ПО c.Node_base, c.Node_forslag

ЗАКАЗАТЬ ПО c.Node_base desc

person user1613212    schedule 03.09.2012