0

我收到此错误,但仅在按特定列分组时:

Arithmetic overflow error converting expression to data type int.

我无法理解为什么。这是导致它的查询(求和函数是罪魁祸首):

SELECT  a.AtgardAvvattningId, 
        a.ObjektId,
        sum(p.SlutLopLangd - p.StartLopLangd) As TotalLangd
    FROM AtgardAvvattning a 
        INNER JOIN Objekt o ON o.ObjektId = a.ObjektId 
        INNER JOIN Position p ON p.AvvattningAtgardId = a.AtgardAvvattningId 
        INNER JOIN Vna v ON v.PositionId = p.PositionId 
    WHERE v.OID IN (...) 
    GROUP BY a.AtgardAvvattningId, a.ObjektId, o.AtgardsDatum
    ORDER BY a.ObjektId

p.SlutLopLangd 和 p.StartLopLangd 都是 int 列。如果我在求和之前将值转换为 bigints,它会起作用:

    sum(CONVERT(bigint, p.SlutLopLangd - p.StartLopLangd)) As TotalLangd

给出这个结果:

AtgardAvvattningId 对象标识符 TotalLangd
DC9... 9B2... 25684
电子病历... 9B2... 25700
3D0... 9B2... 170005
959... 9B2... 170005
贝... 214... 11814
C31... 214... 11815

如您所见,没有总和接近 int 的极限。奇怪的是,如果我像这样在 group by 子句中包含 positionId,它不会引发错误:

SELECT  a.AtgardAvvattningId, 
        a.ObjektId,
        sum(p.SlutLopLangd - p.StartLopLangd) As TotalLangd
    FROM AtgardAvvattning a 
        INNER JOIN Objekt o ON o.ObjektId = a.ObjektId 
        INNER JOIN Position p ON p.AvvattningAtgardId = a.AtgardAvvattningId 
        INNER JOIN Vna v ON v.PositionId = p.PositionId 
    WHERE v.OID IN (...) 
    GROUP BY a.AtgardAvvattningId, a.ObjektId, o.AtgardsDatum, p.PositionId
    ORDER BY a.ObjektId

在这种情况下,AtgardAvvattning 和 Position 之间是一对一的关系。此查询给出与上述完全相同的结果。

当值如此之小时,为什么首先会引发算术溢出?为什么它在第二个中起作用?有什么不同?我知道没有数据和表结构可能很难给出答案,但任何提示都会有所帮助。

更新:

完全使用此查询删除组时:

    SELECT  a.AtgardAvvattningId, 
            a.ObjektId,
            p.PositionId,
            v.VnaId,
            p.StartLopLangd,
            p.SlutLopLangd,
            p.SlutLopLangd - p.StartLopLangd as Subtraction
        FROM AtgardAvvattning a 
            INNER JOIN Objekt o ON o.ObjektId = a.ObjektId 
            INNER JOIN Position p ON p.AvvattningAtgardId = a.AtgardAvvattningId 
            INNER JOIN Vna v WITH (NOLOCK) ON v.PositionId = p.PositionId 
        WHERE v.OID IN (...) 
        ORDER BY a.ObjektId

结果根本没有多少行:

AtgardAvvattningId 对象标识符 职位编号 VnaId StartLopLangd 荡妇LopLangd 减法
DC96... 9B2... 473... 1345183 168501 174922 6421
ECD4... 9B2... 07E... 1252649 74602 81027 6425
ECD4... 9B2... 07E... 1252651 74602 81027 6425
ECD4... 9B2... 07E... 1252652 74602 81027 6425
ECD4... 9B2... 07E... 1252650 74602 81027 6425
DC96... 9B2... 473... 1345180 168501 174922 6421
DC96... 9B2... 473... 1345181 168501 174922 6421
DC96... 9B2... 473... 1345182 168501 174922 6421
3D08... 公元前9... F18... 1374284 199000 233001 34001
3D08... 公元前9... F18... 1374283 199000 233001 34001
9590... 公元前9... 二维... 1374285 16591 50592 34001
9590... 公元前9... 二维... 1374286 16591 50592 34001
9590... 公元前9... 二维... 1374287 16591 50592 34001
9590... 公元前9... 二维... 1374289 16591 50592 34001
9590... 公元前9... 二维... 1374288 16591 50592 34001
3D08... 公元前9... F18... 1374281 199000 233001 34001
3D08... 公元前9... F18... 1374280 199000 233001 34001
3D08... 公元前9... F18... 1374282 199000 233001 34001
C31B... 214... B20... 1349999 32756 44571 11815
BEC3... 214... F21... 1349998 205022 216836 11814

但是,您对行求和,应该很难达到 int 溢出限制。

4

1 回答 1

5

最终值实际上并不重要。可能发生的情况是,在您的某个时刻,您SUM会超过最大值 (2,147,483,647) 或最小值 (-2,147,483,648)int并得到错误。

举个例子:

SELECT SUM(V.I)
FROM (VALUES(2147483646),
            (2),
            (-2006543543))V(I);

这可能会产生相同的错误:

将表达式转换为数据类型 int 时出现算术溢出错误。

然而,结果SUM将是 140,940,105(远低于最大值)。这是因为如果 2147483646先将和2相加,则得到2147483648,它大于 a 的最大值int。如果您先CAST/CONVERT值,则不会收到错误消息:

SELECT SUM(CONVERT(bigint,V.I))
FROM (VALUES(2147483646),
            (2),
            (-2006543543))V(I);
于 2022-01-20T14:59:45.457 回答