【问题标题】:Using ISNUMERIC fails in condition在条件下使用 ISNUMERIC 失败
【发布时间】:2017-04-27 10:49:01
【问题描述】:

我有一张这样的表(简化版):

CREATE TABLE #table (Id INT, Field NVARCHAR(MAX))
INSERT INTO #table VALUES (1, 'SomeText')
INSERT INTO #table VALUES (2, '1234')

由于某些原因,我需要查询此表并获取 Field 的总和(如果它是数字),如果不是则返回 ''。我试过这样:

SELECT CASE WHEN ISNUMERIC(Field) = 1 THEN SUM(CONVERT(MONEY, Field)) ELSE '' END
FROM #table
GROUP BY Field

但是这个查询会导致以下异常:

无法将 char 值转换为货币。 char 值的语法不正确。

我什至将 ELSE 案例从 '' 更改为 0,但我仍然收到相同的消息。

为什么会出现异常?据我所知,SUM(...)不应该在ISNUMERIC(Field)返回0时执行。

【问题讨论】:

  • 无论如何这都会失败,因为CASE 表达式只能返回一种数据类型。在您的情况下,您在 MONEY 数据类型(返回 MONEY)或 '' 上使用 SUM,这显然是一个字符串
  • @Lamak 这就是为什么我将'' 更改为0 以检查这是否有帮助。但是,该消息仍然出现。
  • 因为您应该在SUM 中使用CASE 表达式,对于初学者:SUM(CASE WHEN ISNUMERIC(Field) = 1 THEN Field END)
  • 这很重要。但是为什么我把它放在SUM外面时会出现错误?
  • 虽然您已经接受了答案,但我会提醒您不要在与此类似的大多数情况下使用 ISNUMERIC。仅有的潜在值是 varchar 和 int 吗?

标签: sql-server sql-server-2008 tsql type-conversion


【解决方案1】:
Select sum(case when  ISNUMERIC(Field)=1 then cast(field as money) else 0 end)
 from #table
 Group By Field

返回

(No column name)
1234.00
0.00

【讨论】:

  • 谢谢,它现在可以工作了 :) 唯一我不明白的是为什么我只在将 CASE 语句留在 SUM 之外时才得到异常。
  • @diiN_ 乐于助人。对于总和之外的情况,您将获得数据类型冲突。在内部,我们对数据类型进行规范化。
【解决方案2】:

使用混合数据类型可能会很痛苦。在可能的情况下,考虑避免这种情况的桌子设计。更复杂的是,IsNumeric 并不总是返回 what you might expect

在聚合之前过滤掉非数字是一种方法:

SELECT 
    SUM(CONVERT(MONEY, Field)) 
FROM 
    #table
WHERE
    ISNUMERIC(Field) = 1
GROUP BY 
    Field
;

【讨论】:

  • 问题是我还需要那些非数字字段的值(例如0)。
  • @JohnCappelletti 提供了比我自己更好的解决方案。这会做你想做的。
猜你喜欢
  • 2015-03-25
  • 1970-01-01
  • 2018-03-19
  • 2011-04-24
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2019-04-08
相关资源
最近更新 更多