patternsqlMinor
SQL Server SUM in subquery causing arithmetic overflow when the SUM is less than a 32-bit int
Viewed 0 times
thebitsqloverflowthansubquerylesscausingsumserver
Problem
I have a database that has
I have the following query:
which is throwing an exception:
Recently, the
However, I know and have verified that there are no
If I append
I know I can just convert it to a
Is it internally summing the entire Inventory table for some reason?
Any insight would be greatly appreciated.
Estimated query plan: https://www.brentozar.com/pastetheplan/?id=BJETnFUpa
Manifest's which contain multiple Inventory items. Each inventory item has a integer NetWeight.I have the following query:
SELECT
ID,
(SELECT SUM(NetWeight) FROM Inventory WHERE Inventory.ManifestID = Manifest.ID)
FROM Manifestwhich is throwing an exception:
Arithmetic overflow error converting expression to data type int. and I do not understand why.Recently, the
Inventory table has exceeded the size of an int if you SUM(NetWeight) with no filter.However, I know and have verified that there are no
Manifest's with a value greater than 100,000 for that subquery.If I append
WHERE ID > 0 to the end of the query, it runs fine. All Manifest IDs are greater than 0, so this is theoretically equivalent to having no filter at all.I know I can just convert it to a
bigint and continue with my day, but I want to understand why SQL is overflowing.Is it internally summing the entire Inventory table for some reason?
Any insight would be greatly appreciated.
Estimated query plan: https://www.brentozar.com/pastetheplan/?id=BJETnFUpa
Solution
The top branch of the execution plan selects all 1,098,300 rows from
The output of this (estimated 6 groups) is merge joined onto
Presumably there exists a
Maybe rows where
You could try changing the query to
to get these rows eliminated earlier in the plan (Fiddle).
You might also evaluate an index on
to avoid reading these rows entirely and provide a useful covering index for the aggregation by
Inventory and performsSELECT SUM(NetWeight),
ManifestID
FROM Inventory
GROUP BY ManifestIDThe output of this (estimated 6 groups) is merge joined onto
Manifest (with a right outer join meaning that all rows from Manifest are preserved).Manifest has a cardinality of 5 rows.Presumably there exists a
ManifestID in Inventory which is causing this overflow for a group but is unmatched in Manifest so is eliminated by the join.Maybe rows where
ManifestID is NULL?You could try changing the query to
SELECT
ID,
(SELECT SUM(NetWeight) FROM Inventory WHERE Inventory.ManifestID = Manifest.ID AND Inventory.ManifestID IS NOT NULL)
FROM Manifestto get these rows eliminated earlier in the plan (Fiddle).
You might also evaluate an index on
Inventory(ManifestID) INCLUDE (NetWeight) WHERE (ManifestID IS NOT NULL)to avoid reading these rows entirely and provide a useful covering index for the aggregation by
ManifestID.Code Snippets
SELECT SUM(NetWeight),
ManifestID
FROM Inventory
GROUP BY ManifestIDSELECT
ID,
(SELECT SUM(NetWeight) FROM Inventory WHERE Inventory.ManifestID = Manifest.ID AND Inventory.ManifestID IS NOT NULL)
FROM ManifestInventory(ManifestID) INCLUDE (NetWeight) WHERE (ManifestID IS NOT NULL)Context
StackExchange Database Administrators Q#337534, answer score: 4
Revisions (0)
No revisions yet.