算术溢出取决于按列分组
Arithmetic overflow depending on group by columns
我收到此错误,但仅在按特定列分组时出现:
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
ObjektId
TotalLangd
DC9...
9B2...
25684
ECD...
9B2...
25700
3D0...
9B2...
170005
959...
9B2...
170005
BEC...
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 之间是一对一的关系。此查询给出与上面完全相同的结果。
当值这么小时,为什么首先会引发算术溢出?为什么它在第二个工作?有什么不同?我知道如果没有数据和 table 结构可能很难给出答案,但任何提示都会有所帮助。
更新:
当完全使用此查询删除组时:
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
ObjektId
PositionId
VnaId
StartLopLangd
SlutLopLangd
Subtraction
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...
9BC...
F18...
1374284
199000
233001
34001
3D08...
9BC...
F18...
1374283
199000
233001
34001
9590...
9BC...
A2D...
1374285
16591
50592
34001
9590...
9BC...
A2D...
1374286
16591
50592
34001
9590...
9BC...
A2D...
1374287
16591
50592
34001
9590...
9BC...
A2D...
1374289
16591
50592
34001
9590...
9BC...
A2D...
1374288
16591
50592
34001
3D08...
9BC...
F18...
1374281
199000
233001
34001
3D08...
9BC...
F18...
1374280
199000
233001
34001
3D08...
9BC...
F18...
1374282
199000
233001
34001
C31B...
214...
B20...
1349999
32756
44571
11815
BEC3...
214...
F21...
1349998
205022
216836
11814
无论对行求和,都很难达到 int 溢出限制。
最终值实际上并不重要。可能发生的情况是,在您的 SUM
中的某个时刻,您超过了 int
的最大值 (2,147,483,647) 或最小值 (-2,147,483,648) 并收到错误。
举个例子:
SELECT SUM(V.I)
FROM (VALUES(2147483646),
(2),
(-2006543543))V(I);
这可能会产生相同的错误:
Arithmetic overflow error converting expression to data type int.
然而,SUM
的结果将是 140,940,105(远低于最大值)。这是因为if2147483646
和2
先求和,然后得到2147483648
,比[=13的最大值大=].如果您先 CAST
/CONVERT
值,则不会出现错误:
SELECT SUM(CONVERT(bigint,V.I))
FROM (VALUES(2147483646),
(2),
(-2006543543))V(I);
我收到此错误,但仅在按特定列分组时出现:
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 | ObjektId | TotalLangd |
---|---|---|
DC9... | 9B2... | 25684 |
ECD... | 9B2... | 25700 |
3D0... | 9B2... | 170005 |
959... | 9B2... | 170005 |
BEC... | 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 之间是一对一的关系。此查询给出与上面完全相同的结果。
当值这么小时,为什么首先会引发算术溢出?为什么它在第二个工作?有什么不同?我知道如果没有数据和 table 结构可能很难给出答案,但任何提示都会有所帮助。
更新:
当完全使用此查询删除组时:
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 | ObjektId | PositionId | VnaId | StartLopLangd | SlutLopLangd | Subtraction |
---|---|---|---|---|---|---|
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... | 9BC... | F18... | 1374284 | 199000 | 233001 | 34001 |
3D08... | 9BC... | F18... | 1374283 | 199000 | 233001 | 34001 |
9590... | 9BC... | A2D... | 1374285 | 16591 | 50592 | 34001 |
9590... | 9BC... | A2D... | 1374286 | 16591 | 50592 | 34001 |
9590... | 9BC... | A2D... | 1374287 | 16591 | 50592 | 34001 |
9590... | 9BC... | A2D... | 1374289 | 16591 | 50592 | 34001 |
9590... | 9BC... | A2D... | 1374288 | 16591 | 50592 | 34001 |
3D08... | 9BC... | F18... | 1374281 | 199000 | 233001 | 34001 |
3D08... | 9BC... | F18... | 1374280 | 199000 | 233001 | 34001 |
3D08... | 9BC... | F18... | 1374282 | 199000 | 233001 | 34001 |
C31B... | 214... | B20... | 1349999 | 32756 | 44571 | 11815 |
BEC3... | 214... | F21... | 1349998 | 205022 | 216836 | 11814 |
无论对行求和,都很难达到 int 溢出限制。
最终值实际上并不重要。可能发生的情况是,在您的 SUM
中的某个时刻,您超过了 int
的最大值 (2,147,483,647) 或最小值 (-2,147,483,648) 并收到错误。
举个例子:
SELECT SUM(V.I)
FROM (VALUES(2147483646),
(2),
(-2006543543))V(I);
这可能会产生相同的错误:
Arithmetic overflow error converting expression to data type int.
然而,SUM
的结果将是 140,940,105(远低于最大值)。这是因为if2147483646
和2
先求和,然后得到2147483648
,比[=13的最大值大=].如果您先 CAST
/CONVERT
值,则不会出现错误:
SELECT SUM(CONVERT(bigint,V.I))
FROM (VALUES(2147483646),
(2),
(-2006543543))V(I);