【问题标题】:Calculating SQL Average with non-numeric data in Table使用表中的非数字数据计算 SQL 平均值
【发布时间】:2015-03-11 08:11:47
【问题描述】:

我有一个在这个 nvarchar 上失败的 SQL 查询,尽管在我看来它被适当地保护以使强制转换工作。我试图在我只有读取权限的数据库上获取正确格式的数值的平均值。

select TagName, count(TagName) as Freq,
       sum(isnumeric(value)) as GoodNums,
       avg(case isnumeric(value) when 1 then cast(value as numeric) else 0 end) as "Avg",
       Min(Timestamp) as StartTime,
       Max(Timestamp) as EndTime 
 from HH_Data_9 group by TagName

但是,我从来没有真正完全理解 CASE、聚合函数和 GROUP_BY 组合的 SQL 语法,所以也许我只是写错了(在发布之前尝试了很多东西)。请注意,“GoodNums”列有效并且给出了合理的答案,但是当我将“Avg”列添加到查询中时,整个事情都会出错:

Msg 8114, Level 16, State 5, Line 1
Error converting data type nvarchar to numeric.

顺便说一下,这是 Microsoft SQL Server 2014。有什么想法吗?

【问题讨论】:

  • isnumeric() 并不完美——$(货币符号)、,.(仅限分隔符)等值也是它的数字。也许这就是问题所在?
  • 使用 try_cast 代替 case 表达式。它适用于 SQL Server 2012 及更高版本。
  • 好的,耶稣,谢谢。如果您将其作为带有代码的答案提交,我会将其标记为正确。
  • 仍在等待您 (Jesús López) 发布我可以标记为正确的答案。

标签: sql sql-server group-by aggregate-functions


【解决方案1】:

只是想提醒一下,这种方法非常危险。考虑以下表结构:

CREATE TABLE TestTable
    (
      FieldType NVARCHAR(50) ,
      FieldValue NVARCHAR(50)
    )
GO

INSERT  INTO dbo.TestTable
VALUES  ( 'INT', '5' ),
        ( 'INT', '15' ),
        ( 'MONEY', '5.5' )


SELECT  *
FROM    dbo.TestTable
WHERE   FieldType = 'INT'
        AND CAST(FieldValue AS INT) > 10

在我的机器上这个查询有效,但这里的事情是很多人假设这个谓词将从左到右计算。但这是不正确的。 SQL Server 引擎可能决定从右到左计算此表达式。在这种情况下,您将收到 Conversion failed 错误。它被称为ALL-AT-ONCE 原则。但是在您的示例中,这不适用,只是想提一下。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2013-03-18
    • 1970-01-01
    相关资源
    最近更新 更多