操作数数据类型 nvarchar 对于 avg 运算符无效

Operand Datatype nvarchar is invalid for avg operator

我需要找到这个名为“Edges”的列的平均值。 其中的值类型如下:(注意:还有一堆 NULL

 EDGES
 1. 1,362,797
 2. 204,919 
 3. 26,138 948,570 
 4. 111,471 5,858 

我已经尝试 运行 显示非空值的查询:

SELECT AVG(Edges) AS test from 
(SELECT [Edges] as Edges FROM dbo.tracker
WHERE [Edges] like '%[^0-9]%') as a

我得到的错误是这样的:“操作数数据类型 nvarchar 对于 avg 运算符无效。

平均此列的查询是什么?

您可以使用 applystring_split():

select t.*, e.avg_edges
from t cross apply
     (select avg(try_cast(s.value as numeric)) as avg_edges
      from string_split(t.edges, ',') s
     ) e;

Here 是一个 db<>fiddle.

注意:这将忽略非数字值,例如 138 948。但是你的问题没有解释如何处理这些值。

编辑:

如果您想要所有行的平均值:

select avg(e.edge)
from t cross apply
     (select try_cast(s.value as numeric) as edge
      from string_split(t.edges, ',') s
     ) e;

首先:如您所见,将数字存储为字符串是一个非常糟糕的主意。您应该相应地更改您的数据模型。

然后,您要查找包含非数字字符的字符串。这看起来很奇怪。这意味着从像

这样的值列表中
1,000
2,000
3000
4000

你只会考虑那些有千位分隔符并得到 (1000 + 2000 / 2) = 1500 的结果。(并且 table 中不能有非数字的字符串字符并且不代表数字,因为那样的话尝试计算平均值当然会完全失败。)

无论如何,如果您想要这个并且只要这是您的数据模型,您就必须将字符串转换为数字。不幸的是,SQL 服务器的类型转换功能至少可以说非常有限。 DBMS 应该能够隐式地从字符串转换为数字,这有效:

select '948570' + 0;

但这失败了:

select '948,570' + 0;

还有这个:

select '948,570' + 0.0;

甚至这个:

select '948570' + 0.0;

由于千位分隔符只是美化器,最好的办法是完全删除它们(使用 REPLACE)并显式转换。但请注意,SQL 服务器在检测整数时倾向于使用小学整数数学(例如 1 / 2 = 0,而不是 0.5)。因此,尽管您的字符串表示整数,请将它们转换为 DECIMAL,而不是 INT。

SELECT AVG(CONVERT(DECIMAL, REPLACE(edges, ',', ''))) as avg_edges
FROM dbo.tracker
WHERE edges like '%[^0-9]%'