【问题标题】:ROW_NUMBER() function returns varchar value instead of intROW_NUMBER() 函数返回 varchar 值而不是 int
【发布时间】:2012-06-28 08:23:24
【问题描述】:

我正在使用 SQL Server 中的 ROW_NUMBER() 函数来创建一个名为 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

【问题讨论】:

  • 误诊。它无法转换第 6 行的字符串 'RowNumber'。这不是字段名称,它只是一个字符串。也可以说WHERE 'ThisIsAString' &lt; 11。由于&lt; 需要两个值是相同的类型,它尝试将字符串转换为 INT,但失败了。
  • '这是一个字符串文字。' “这是一个带引号的标识符。”请注意区别。

标签: sql sql-server type-conversion row-number


【解决方案1】:

您不能在 WHERE 子句中引用来自 SELECT 子句的计算列 - 即使可以,单引号也会引入字符串文字,而不是列引用。使用 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 - 它不是保留字,也不包含特殊字符。

【讨论】:

  • 我应该把它放在 HAVING 子句中吗?
  • @MOLAP - 不,您也不能从 HAVING 引用它。
  • @MOLAP - 我已经更新了查询 - 我还没有真正阅读您在 ROW_NUMBER 中尝试执行的操作,我想我已经将其调整为您现在想要的。
  • 好的,谢谢。我最终使用了一个子查询: Select * from (my query without the ORDER BY statement) as d WHERE where RowNumber
【解决方案2】:

在声明中

WHERE 'RowNumber' <11

您将字符串文字“RowNumber”与数字 11 进行比较。

只需删除引号:

WHERE RowNumber <11

【讨论】:

  • 这会导致:列名“行号”无效。
  • @MOLAP:您不能引用您刚刚在同一级别 SELECT 中定义的列 WHERE - 您需要将定义 RowNumber 的语句包装到子查询或 CTE 中.
  • 是的 - 像这样应用过滤器不起作用。正如@Damien_The_Unbeliever 所说。 (假设您会发现并在遇到错误时尝试自己修复它 - 我尽量不要用勺子喂太多)。
【解决方案3】:

使用[RowNumber] 而不是"RowNumber"

SET QUOTED_IDENTIFIER 为ON(默认)时,所有由双引号分隔的字符串都被解释为对象标识符。

您还必须使用子查询在 where 子句中引用 row_number(),例如:

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

【讨论】:

  • 不认为 Top 会起作用,它会返回前 11 行,而不是每个分区的前 11 行?
  • 我刚刚测试了TOP功能,在这种情况下它不起作用。
  • @JonEgerton:是的,top 将返回前 11 个(base, forslag) 组。 row_number() 变体做了一些奇怪的事情:前 11 个(base) 组然后按(base, forslag) 分组。不确定这是否是 OP 所追求的。
  • 这个答案的第 1 部分可以使它工作。 (使用子查询来引用新字段 RowNumber。
  • 这不就是CROSS APPLY被发明出来的原因吗?
【解决方案4】:

选择 row_number() over (order by c.Node_base) 作为 RowNumber, c.Node_base, c.Node_forslag, sum(Score)

FROM t_input as c

WHERE 'RowNumber'

按 c.Node_base、c.Node_forslag 分组

按 c.Node_base desc 排序

【讨论】:

    猜你喜欢
    • 2015-03-03
    • 2016-05-28
    • 2021-07-19
    • 1970-01-01
    • 1970-01-01
    • 2018-03-08
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多