Arithmetic overflow error converting numeric to data type numeric. AVG Select Statment - sql

I am trying to average the values for a given month using the AVG function but it's throwing the Arithmetic overflow error converting numeric to data type numeric. After some Googling, it looks like the common cause for this is trying to store the output of the AVG function into a variable/column that has a datatype not suitable for the incoming value. I am receiving this error just trying to SELECT the values.
--Hours (DECIMAL(18,4)), Starts (DECIMAL(18,4))
SELECT ID, Avg(Hours), Avg(Starts)
FROM MonthlyReadings
WHERE ReadingDate < '2016-03-01'
AND ReadingDate > DATEADD(MM, -36, '2016-03-01')
AND MONTH(ReadingDate) = 1
GROUP BY ID
Any idea why I'm getting this error?

Resulting datatype is inherited from the field you're aggregating. You need a datatype large enough to hold the SUM() in order to calculate the AVG(), you should be fine with FLOAT or expand your DECIMAL:
SELECT ID, Avg(CAST(Hours AS FLOAT)), Avg(CAST(Starts AS FLOAT))
FROM MonthlyReadings
WHERE ReadingDate < '2016-03-01'
AND ReadingDate > DATEADD(MM, -36, '2016-03-01')
AND MONTH(ReadingDate) = 1
GROUP BY ID

Related

How to convert nvarchar into int type for SQL Server

I tried to count the total the column [Trans Det Amt ex Tax] like the following:
SELECT
Loyalty_Type_Code,
COUNT([Loyalty_Number]),
FORMAT(SUM([Trans_Det_Amt_ex_Tax]), '##,###,###,##0')
FROM
CRM_POWERBI_RETAIL
WHERE
Trans_Hdr_Sale_Date BETWEEN '2019-01-01' AND '2019-10-31'
GROUP BY
Loyalty_Type_Code
UNION
SELECT
'TOTAL',
COUNT(*) AS CCC,
COUNT(*) AS BBB
FROM
CRM_POWERBI_RETAIL
I get this error:
Msg 245, Level 16, State 1, Line 39
Conversion failed when converting the nvarchar value '67,527,726,031' to data type int.
So I tried to convert this to INT type by using the following:
SELECT
CONVERT(INT, Trans_Det_Amt_ex_Tax)
FROM
CRM_POWERBI_RETAIL
But the result still said
Conversion failed when converting the nvarchar value '67,527,726,031' to data type int
Please let me know how to fix this.
Thank you for all answers.
Don't convert the value to a string:
SELECT Loyalty_Type_Code , COUNT([Loyalty_Number]),
SUM([Trans_Det_Amt_ex_Tax]))
FROM CRM_POWERBI_RETAIL
WHERE Trans_Hdr_Sale_Date BETWEEN '2019-01-01' AND '2019-10-31'
GROUP BY Loyalty_Type_Code
UNION
SELECT 'TOTAL', COUNT(*) AS CCC, COUNT(*) AS BBB
FROM CRM_POWERBI_RETAIL;
All the types in a UNION ALL need to be the same. If it sees a string and an integer -- as in the third column -- it will try to convert the string to an integer. That is not possible with commas.
Alternatively, you can convert both columns to strings. A simpler method uses GROUPING SETS:
SELECT COALESCE(Loyalty_Type_Code, 'Total'),
COUNT([Loyalty_Number]),
FORMAT(SUM([Trans_Det_Amt_ex_Tax]), '##,###,###,##0')
FROM CRM_POWERBI_RETAIL
WHERE Trans_Hdr_Sale_Date BETWEEN '2019-01-01' AND '2019-10-31'
GROUP BY GROUPING SETS ( Loyalty_Type_Code, () );
select CONVERT(bigint, Trans_Det_Amt_ex_Tax)
int cant hold number that big
If you want to convert the value to a string, try removing the commas and using a data type cast that is large enough to store that data:
SELECT CAST(REPLACE('67,527,726,031',',','') AS BIGINT);
This will strip the commas and store the data as a BIGINT.
I'm not 100% sure, but you may need to CAST the SUM as a larger data type if you're going to be adding up a lot of values.
DB Fiddle

show data with shipmentdate bigger than today

i am trying to pulling data for all shipments with shipmentdate greater than todays date. However, I cant figure out an easy conversion of the format of the nvarchar, i get a out of range value error when trying to run this:
select *
from dbo.BAS_CT_RAW_ARCHIVE_TBL
where SHIPMENTDATE > GETDATE()
Msg 242, Level 16, State 3, Line 1 The conversion of a nvarchar data
type to a datetime data type resulted in an out-of-range value.
Try:
select *
from dbo.BAS_CT_RAW_ARCHIVE_TBL
where convert(date, SHIPMENTDATE, 103) > GETDATE()
To see how to use convert with non-standard dates see this.
Further consideration: use proper datatypes for columns, i.e. don't store dates as strings, but as date datatype - it will prevent you from having such problems.
according to your data format that got from comment below should work
select * from dbo.BAS_CT_RAW_ARCHIVE_TBL
where CONVERT(date, SHIPMENTDATE, 103) > convert(date, GETDATE())

sql converting date to show

I want to get the total sum from a the table from the previous day. I get an error
My code:
select
date_paid, sum(paid_amount) as amount
from
till1
where
date_paid = dateadd(day, datediff(day, 0, getdate()), 0)
group by
date_paid
I want to get a result something like this:
I get the following error:
The conversion of a char data type to a datetime data type resulted in an out-of-range datetime value
Presumably, this is SQL Server. You can fix the syntax error by using try_convert():
select date_paid, sum(paid_amount) as amount
from till1
where try_convert(date, date_paid) = cast(getdate() as date)
group by date_paid;
However, the real solution is to fix the data. Dates should not be stored as strings.

i just want to get past 3 months transaction

need help. i just want to get past 3 months transaction.
SELECT *
FROM transaction
WHERE TransactionDate >= GETDATE()-90
transactionDate is a INT type with this format YYYYMMDD (ex. 20160812)
i got this error
Arithmetic overflow error converting expression to data type datetime.
any help will do
You can't convert an int directly to a date. However, you can convert a string in YYYYMMDD format. So, try this:
WHERE cast(cast(TransactionDate as varchar(255)) as date) >= GETDATE() - 90
Alternatively, you could do all the conversion on the current date side:
WHERE TransactionDate >= CONVERT(INT, CONVERT(VARCHAR(255), GETDATE() - 90, 112))
The advantage of this method is that the engine can use an index on TransactionDate.
That said, the right way to store the column is as a DATE. SQL Server has built-in date/time data types for a reason; there is a lot of direct support for them. Use the capabilities of the database.

trouble with string to date conversion

Greetings StackWarriors....
I am in need of some help.
I have this SQL Select statement:
SELECT GEOID, cast(LEFT(PP.PurchaseDate,4) + RIGHT(Left(PP.PurchaseDate,6),2) as integer) AS Month
FROM PropertyParametersNew PP
join PropertyTracts PT on PP.ParcelID = PT.PARCELID
WHERE
PP.PurchaseDate >0
and convert(datetime, PP.PurchaseDate, 112)>= DATEADD(MONTH,-1,getdate())
The intent in this query is trying to get GEOID, and the year/month associated in the PurchaseDate Column.
and I'm getting this error:
Msg 242, Level 16, State 3, Line 1 The conversion of a varchar data
type to a datetime data type resulted in an out-of-range value.
I realized that inside that column, I have yyyymmdd formatted dates that have 00's in the mm and dd. Examples include 20130000 and 20120300.
I am trying to rephrase the sql query to handle those entries.
My owners say that 0000 should reflect January 1, and 00 should reflect the 1st of the month.
How can I restructure this SQL statement to reflect this value, so I can get Year/Month combo without the conversion failure?
Thanks.
You can use REPLACE to fix values in PurchaseDate, then simply use fixed field in its place:
(edit made after correct remark by #t-clausen)
SELECT GEOID,
cast(LEFT(x.PurchaseDate,4) + RIGHT(Left(x.PurchaseDate,6),2) as integer) AS Month
FROM PropertyParametersNew PP
CROSS APPLY (SELECT CASE WHEN RIGHT(PP.PurchaseDate, 4) = '0000'
THEN LEFT(PP.PurchaseDate, 4) + '0101'
WHEN RIGHT(PP.PurchaseDate, 2) = '00'
THEN LEFT(PP.PurchaseDate, 6) + '01'
ELSE PurchaseDate
END) x(PurchaseDate)
JOIN PropertyTracts PT on PP.ParcelID = PT.PARCELID
WHERE
PP.PurchaseDate >0
and convert(datetime, x.PurchaseDate, 112)>= DATEADD(MONTH,-1,getdate())
If, for example, PP.PurchaseDate is equal to 20130000, then the above query sets x.PurchaseDate equal to 20130101 and uses this value inside CONVERT as well as in SELECT clause.
For all this to work PP.PurchaseDate must be of fixed length (8 characters).
Best senario would be fixing the data to date second best would be changing your dates to be valid dates as char(8).
But your question is how to write your select.
You should not convert the purchase date to datetime, you should go the other way and convert the getdate() to char(8). This will give you a better performance. Then there is the issue of the varchar being 20130000. You can compensate by subtracting 1 from the date and ask for a greater value instead of greater equal.
The answer is quite simple and improves performance because you don't have a conversion on your column:
WHERE
PP.PurchaseDate >0
and PP.PurchaseDate >
CONVERT(char(8),DATEADD(MONTH,-1,getdate())-1, 112)