Using cast inside sum or outside ?

ahmed salah 3,216 Reputation points
2020-12-22T14:53:24.92+00:00

I work on sql server 2012 I face issue using cast first or sum ?
cast (sum(a) as decimal(18,2)
or
sum(cast (a as decimal(18,2)))

which is correct and more speed

a is integer need to convert to decimal

so using cast inside sum or outside

Developer technologies Transact-SQL
SQL Server Other
{count} votes

Accepted answer
  1. Tom Phillips 17,771 Reputation points
    2020-12-28T13:59:20.127+00:00

    Just to be clear.

    In your specific example, you can do an outer cast.

    However, if you were going the other way, decimal to int, you would get different results depending on where you do that cast. Only you can determine which is correct.

    DECLARE @testtbl TABLE (nums DECIMAL(18,2))
    INSERT INTO @testtbl VALUES 
    (1.1),
    (2.2),
    (3.322),
    (4.44)
    
    
    SELECT CAST(SUM(nums) AS INT)  -- = 11
    FROM @testtbl
    
    
    SELECT SUM(CAST(nums AS INT)) -- = 10
    FROM @testtbl
    
    0 comments No comments

5 additional answers

Sort by: Most helpful
  1. Viorel 122.5K Reputation points
    2020-12-22T14:59:45.103+00:00

    In my opinion, if you have 1000 numbers, for example, then it is better to have a single cast instead of 1000 casts. Therefore, “cast(sum(a) as decimal” (one cast) seems better than “sum(cast(a) as decimal)” (1000 casts).

    0 comments No comments

  2. Tom Cooper 8,481 Reputation points
    2020-12-22T16:27:32.773+00:00

    If you want the result to be decimal(18,2), you should use

    cast(sum(a) as decimal(18,2))

    which will give you as decimal(18,2) result. But the result of

    sum(cast(a as decimal(18,2)))

    will give you as decimal(38,2) result. If you run

    create table #Fooa(a int);  
    insert #Fooa(a) values(1), (2), (3);  
    select sum(cast(a as decimal(18,2))) as x into #Foob from #Fooa;  
    exec sp_help #Foob;  
    go  
    drop table #Fooa;  
    go  
    drop table #Foob;  
    

    you will see the result has precision of 38, not 18.

    Also, I agree with @Viorel that casting the sum will be faster the summing the cast (although I think the difference in performance will be very small). Therefore, for both reasons, you should go with casting the sum.

    Tom

    0 comments No comments

  3. David Browne - msft 3,851 Reputation points
    2020-12-22T17:09:25.413+00:00

    You should cast the result to the target type, but only if you're certian that aggregate won't overflow its return type.

    50469-image.png

    https://learn.microsoft.com/en-us/sql/t-sql/functions/sum-transact-sql?view=sql-server-ver15#return-types

    0 comments No comments

  4. Erland Sommarskog 121.4K Reputation points MVP Volunteer Moderator
    2020-12-22T22:49:01.163+00:00

    You should cast the result to the target type, but only if you're certian that aggregate won't overflow its return type.

    It seems reasonable to assume that it will, since else why do we want 16 digits before the decimal point?

    Given Tom's post, the best is maybe

    cast(sum( cast(a as decimal(18,2)) decimal(18,2)

    Just so that Ahmed talks about, if you sum integer values, the result cannot exceed 2.147 milliards, since that is the upper limit of an int. Therefore you need to convert inside the sum to avoid that problem.

    0 comments No comments

Your answer

Answers can be marked as Accepted Answers by the question author, which helps users to know the answer solved the author's problem.