db2: how to remove the decimal from number column? - sql

A very simple query which work
select avg(price) from cars where type = 'electric';
the result is
1
---------------------------------
45000,00000000000
I want to remove the ,00000000000 to obtain
1
---------------------------------
45000
I have tried cast and round but without success.
I'm on Db2
This nice ltrim works fine for all type of cars
select replace(ltrim(replace(price,'0',' ')),' ','0') from cars;
but using with avg return the string with the 00000
select replace(ltrim(replace(avg(price),'0',' ')),' ','0') from cars where type = 'electric';
the result is..
45000.00000000000
:(
Only the , is changed.

casting this value should just work:
select cast(avg(price) as int) as avg_int
from cars
where type = 'electric';

Casting as an integer as suggested by another answer will work.
However, keep in mind that
you'll be truncating any decimal values.
you're converting from one type to another.
You can resolve #1 by casting after ROUND()
select int(round(avg(price),0)) as avg_int
from cars
where type = 'electric'
You can resolve #2 by using DECIMAL() or ZONED() with zero for scale depending on the original column type.
select dec(avg(price),10,0) as avg_dec
from cars
where type = 'electric'
And of course ROUND() could be used with DECIMAL() or ZONED() also...

Related

How to multiply string value to longint in SQL

I have the below data which I want to multiply together, column A times column B to get column C.
A has datatype string and B has datatype long.
A B
16% 894
15% 200
I have tried this expression in query cast(A as int)*B but it is giving me an error.
You can try below way -
select cast(left(A, patindex('%[^0-9]%', A+'.') - 1) as int)*B
from tablename
You need to remove the '%' symbol before attempting your cast. And assuming you are actually wanting to calculate the percentage, then you also need to divide by 100.00.
cast(replace(A,'%','') as int)/100.00*B
Note: You need to use 100.00 rather than 100 to force decimal arithmetic instead of integer. Or you could cast as decimal(9,2) instead of int - either way ensures you get an accurate result.
You may well want to reduce the number of decimal points returned, in which case cast it back to your desired datatype e.g.
cast(cast(replace(A,'%','') as int)/100.00*# as decimal(9,2))
Note: decimal(9,2) is just an example - you would use whatever precision and scale you need.
The syntax of the cast in SQL Server is CAST(expression AS TYPE);
As you cannot convert '%' to an integer so you have to replace that with an empty character
as below:
SELECT cast(replace(A,'%','') AS int);
Finally you can write as below:
SELECT (cast(replace(A,'%','') AS int)/100.00)*B as C;

Conversion failed when converting the varchar value '6276.54' to data type int

I have the below query that keeps throwing the conversion error. I have tried so many ways of making this work but still get the same error. Process of elimination I'm now thinking that this is to do with the hard coded 0.715 value. I'm not sure if or how I force this to be a decimal or if its better to have this SET and a variable at the beginning of my code.
SELECT CAST(DATEPART(yyyy, YEAR) as INT) AS YEAR,
COUNT(ID) AS ID,
SUM(VALUE) AS VALUE,
SUM(PREMIUM) AS PREMIUM,
SUM(try_convert(float,USERID1)) AS VALUE1,
COALESCE(SUM(PREMIUM)/(SUM(try_convert(float,NULLIF(USERID1,0)))*0.715),0) AS 'PROFIT'
SUM(CAST(USERID1 AS float))/SUM(PREMIUM) AS 'PROFIT%'
INTO #YEAR_VALUE
FROM #DATA LT
INNER JOIN dbo.AccountDB P ON LT.ID = P.ID
GROUP BY INCEPTDATE
Any help would be much appreciate.
Thanks in advance
You have some logic back to front, you need to try_parse first, and then do nullif. Try_parse generally returns null if it cannot cast to type specified. You then need to convert null to 0.0
coalesce(sum(premium)/(sum(nullif(try_convert(float,'userId), 0.0)) * 0.715), 0.0) AS 'profit'
Also, use 0.0 for zero if expecting floats or decimals
Hint: save yours and the next person eyes, no need to use uppercase. That was back in the 70's
As it has been mentioned, It could be possible that you have some non-numerical data within that column. I did the best I could with what I can gather from here to throw together a quick mock up and it seems to work for me with data I have entered. Just testing the line of code you seem to be having issues with.
USE DB
GO
CREATE TABLE
Test_Table (
Premium decimal,
userID varchar(20)
)
INSERT INTO
Test_Table VALUES
(
2.5, 1
)
USE DB
GO
SELECT COALESCE(SUM(Premium)/(SUM(try_convert(float,NULLIF(userID,0)))*0.715),0) AS 'PROFIT'
FROM Test_Table;
That may point to either some non-numerical data or another line of code being the issue. Just food for though, I know our data and data types probably aren't the exact same.

Error when aggregating due to conversion from varchar to bigint

Situation:
I want to aggregate a value from a table but i get the following error :
Error converting data type varchar to big int.
I've been reading countless of different solutions online but they don't seem to solve it.
Current query;
So based on the error message, i simply added the CAST function but it still doesnt work.
SELECT
base.target_date AS target_date
, base.game_id AS game_id
, base.device AS device
, ISNULL(CAST(SUM(use_point.point) AS bigint),0) AS result
FROM
cte AS base
LEFT JOIN cte2 AS use_point
ON base.target_date = use_point.target_date
AND base.game_id = use_point.device
AND base.device = use_point.device
GROUP BY
base.target_date
, base.device
, base.game_id
WITH ROLLUP
GO
I'm presuming that use_point.point is a VARCHAR, in which case simply change where you put your CAST statement:
, ISNULL(SUM(CAST(use_point.point AS bigint)), 0) AS result
Note that the CAST now takes place before the SUM.
Use TRY_CAST() instead. And it needs to be an argument to the SUM():
SELECT base.target_date, base.game_id, base.device,
COALESCE(SUM(TRY_CAST(use_point.point as bigint)), 0) as result
FROM . . .
Note that your column aliases are redundant, because you are assigning the default aliases.
You should also fix the data. Don't store numeric values as strings. To find the bad data, you can use:
select points
from use_points
where try_convert(points as bigint) is null and
points is not null;

sqlserver sum with minus

I use sqlserver 2012.
I have a query like this
SELECT SUM(TH.CLEAVE_EARN_DAY), SUM(TH.CLEAVE_DAY),
SUM(TH.CLEAVE_EARN_DAY) - SUM(TH.CLEAVE_DAY)
FROM TH_LEAVE_CARD TH
The result is 0, 14.5, -15
so -15 is wrong. Must be -14.5
any suggestion ?
This is what you can try
SELECT SUM(TH.CLEAVE_EARN_DAY), SUM(TH.CLEAVE_DAY),
SUM(TH.CLEAVE_EARN_DAY)*1.0 - SUM(TH.CLEAVE_DAY)
FROM TH_LEAVE_CARD TH
Multiplying with 1.0 will just give you back decimal value and taking away will give you what you asked for
Try converting all arguments to the same datatype and then do calculation:
SELECT
SUM(CAST(TH.CLEAVE_EARN_DAY AS DECIMAL(18,2))),
SUM(CAST(TH.CLEAVE_DAY AS DECIMAL(18,2))),
SUM(CAST(TH.CLEAVE_EARN_DAY AS DECIMAL(18,2))
- CAST(TH.CLEAVE_DAY AS DECIMAL(18,2))) AS substraction
FROM TH_LEAVE_CARD TH
Also you can combine:
SUM(TH.CLEAVE_EARN_DAY) - SUM(TH.CLEAVE_DAY)
to (if both column are NOT NULL):
SUM(TH.CLEAVE_EARN_DAY - TH.CLEAVE_DAY)
or (thanks Arvo for pointing this):
SUM(ISNULL(TH.CLEAVE_EARN_DAY,0) - ISNULL(TH.CLEAVE_DAY,0))
To perform mathematical operations on columns:
Used columns should be converted into same numeric/decimal data type.
To handle null values you may use ISNULL function.
Ex:
SELECT SUM(TH.CLEAVE_EARN_DAY), SUM(TH.CLEAVE_DAY),
SUM(cast (TH.CLEAVE_EARN_DAY) as decimal(5,1)) - SUM(cast ( (TH.CLEAVE_DAY) as decimal(5,1))
FROM TH_LEAVE_CARD
There is few reason why the result is not as per what you are expecting. In Sql Server any math operation that contains a null would result to null. for example sum(1,2,3,null,4) is equal to null. 1 + null also equal to null.
therefore it would be safer to use isnull function to assign a default value in case the value is null.
for mathematical operation. sql server would do the calculation based on the specified data type. for example int / int = int. therefore the result would be missled. because most of the time int / int = float.
it would be better to change the value to double prior to do any arithmetic operation.
below is the example after include the isnull function as well as cast to float.
SELECT SUM(CAST(ISNULL(TH.CLEAVE_EARN_DAY,0) as double)), SUM(cast(ISNULL(TH.CLEAVE_DAY,0) as double)),
SUM(cast(ISNULL(TH.CLEAVE_EARN_DAY,0) as double)) - SUM(cast(ISNULL(TH.CLEAVE_DAY,0) as double))
FROM TH_LEAVE_CARD TH

SQL: Unable to CAST a query

SELECT CAST ((SUM(r.SalesVolume)/1000) AS decimal(3,3)) FROM RawData r
The above is a part of a query that I am trying to run but returns an error:
Lookup Error - SQL Server Database Error: Arithmetic overflow error converting int to data type numeric.
Not sure what this means.
The result column looks like(Without dividing by 1000 and casting):
Total_Sales_Volume
64146
69814
68259
56318
66585
51158
44365
49855
49553
88998
102739
55713
Tried casting as float but doesnt help.
The Problem is decimal(3,3) --> this means a number with 3 digit, 3 of them behind the decimal point. If you want a number like this 1234567.123 you would have do declare it as decimal(10,3)
Try this:
SELECT CAST ((SUM(r.SalesVolume)/1000.0) AS decimal(6,3)) FROM RawData r
decimal(3,3) means that you allow numbers with 3 digits in total, and 3 of these are behind the comma ... I think you meant decimal(6,3)
EDIT: In addition, you need to to divide by 1000.0, not by 1000.
If you divide by 1000, it is an integer division.
If you divide by 1000.0, then it becomes a decimal division, with commas.
Try following:
SELECT CAST ((SUM(r.SalesVolume)/1000) AS numeric(6,3)) FROM RawData r