Teradata keeps returning zeros for decimals - sql

Casting as decimal with precision 2, keeps returning 00 after the decimal. How do I actually return values?
column1 hourlycolumn1
---------- ------------------
9797 163.00
358 5.00
265 4.00
select top 10
column1,cast(column1/60 as decimal(6,2)) as "hourlycolumn1"
from
....
What I would like to return is below
column1 hourlycolumn1
---------- ------------------
9797 163.28
358 5.96
265 4.41

Your column is an Integer and Integer-division truncates. The cast to decimal is after truncation.
Simply cast before division
column1,cast(column1 as decimal(6,2))/60
Calculations based on Decimals are a bit tricky in Teradata because it's rounded after every step, thus a basic recommendation is to to multiplication before division. See DECIMAL Result Data Type

Related

Calculate dollars to millions returns integer

I am trying to calculate dollar amount (in DB as Decimal(15, 0) NOT NULL) to millions by dividing but as result I get only integer amount.
desired result:
AMOUNT AMOUNT IN MIL
123000 0.1
1123000 1.123
I have this, but it return only 0, 1...
SELECT ... AMOUNT / 1000000 AS "AMOUNT IN MIL" FROM ....
Try to change the datatype to 6 fractional digits before calculation:
cast(amount as decimal(28,6)) / 1000000
You should familiarize yourself with rules of such arithmetic operations. Refer to the Expressions article.
Briefly:
INT / INT = INT
DEC(p, s) / DEC(p', s') = DEC(31, 31-p+s-s')
So, if you want to get DEC(31, X) on INT / INT, you may explicitly cast a numerator to DEC(31-X).
In your case (X=6):
> db2 describe dec(1, 25)/1000000
Column Information
Number of columns: 1
SQL type Type length Column name Name length
-------------------- ----------- ------------------------------ -----------
484 DECIMAL 31, 6 1 1

How to divide integers in Oracle SQL to produce floating point numbers?

I have just started learning Oracle SQL. I am trying to divide two columns of numeric datatype which is same as an integer, I think. I want to create a new column in the table or float data type, divide an existing numeric column by an integer and put its value into the float column. I am using this code for the division and updating part:
update Student set AVERAGE = TOTAL/3;
Here, TOTAL is the numeric column and AVERAGE is float. But when I print the table using:
select * from Student;
, AVERAGE is shown with rounded values of the division. I tried two solutions that I found on the internet:
update Student set AVERAGE = (TOTAL*1.00)/3;
And:
update Student set AVERAGE = cast(TOTAL as float(2))/3;
But both are not working. What am I doing wrong?
Here is the output I am getting:
ROLL_NO SNAME MATHS CHEM PHY TOTAL AVERAGE
---------- --------------- ---------- ---------- ---------- ---------- ----------
101 abcd 56 68 80 204 70
102 efgh 81 78 70 229 80
103 ijkl 69 73 78 220 70
104 mnop 90 89 92 271 90
105 qrst 80 89 79 248 80
First, you need to understand what FLOAT datatype in Oracle means.
The Oracle FLOAT data type is the subtype of the NUMBER data type.
Synatx:
FLOAT(p)
p is precision in Binary bits.
Following formula is used to convert between binary and decimal
precision: Decimal = 0.30103 * Binary
Now, According to the result you are getting, I think your column (AVERAGE) datatype is FLOAT(1).
If you need more precision then you need to alter your table with more precision value in Binary.
Let's take an example:
CREATE TABLE TEST (
f1 FLOAT,
f2 FLOAT(1),
f3 FLOAT(4),
f4 FLOAT(7)
);
INSERT
INTO
TEST(
f1,
f2,
f3,
f4
)
VALUES(
10 / 3,
10 / 3,
10 / 3,
10 / 3
);
select * from TEST;
Output:
db<>fiddle demo
If you do not provide any precision then Oracle will take the maximum precision(126 bits
--> 37 decimal).
In the above example, the data type of the column f1, f2, f3, and f4 is FLOAT, FLOAT(1), FLOAT(4), and FLOAT(7).
The corresponding precision in decimal digits of the column f1, f2 <-- (Your case), f3 and f4 is 37(126 * 0.30103), 1 (1 * 0.30103) <-- (Your case), 2 (4 * 0.30103), and 3 (7 * 0.30103).
So, Conclusion is --> alter your table and change the precision of the AVERAGE column's FLOAT datatype according to your requirement.
Cheers!!
This is a little long for a comment.
The column average is going to be displayed based on the datatype of that column. Oracle will convert the "numbers" being divided so the result is accurate, I think using the number type.
You can run the following code to see that the division result is always the same:
select cast(10 as int) / cast(3 as int),
cast(10 as numeric) / cast(3 as numeric),
cast(10 as float) / cast(3 as float)
from dual;
So the data type of the operands doesn't make a difference.
On the other hand, the data type of the result does. These produce different results:
select cast(10 / 3 as int),
cast(10 / 3 as float),
cast(10 / 3 as number),
cast(10 / 3 as numeric(5, 1))
from dual;
In Oracle the NUMBER data type is already a floating point type. It's unusual in that it's a base-10 floating point number type so it's safe to use for calculations involving money, but it's still a floating point type. Docs here
It is possible to define a NUMBER which holds only integers by defining a subtype or a particular field as having 0 for the scale component, e.g.
nInt_value NUMBER(10,0);
or
SUBTYPE TEN_DIGIT_INTEGER_TYPE IS NUMBER(10,0);
in which case nInt_value will only be able to hold whole numbers of 10 digits or less.
Note that SUBTYPE is only available in PL/SQL - in other words, you can't define a SUBTYPE in a PL/SQL module and then use it as a database field. Docs here

Calculate average of a row in SQL Server

I have the below table..the percent column is of type nvarchar
Data Percent1 Percent2 Percent3
1 3% 4% 6%
2 6% 8% 7%
3 8% 6% 8%
I have to calculate the Avg per line so I get results like
Data Avg
1 4.33%
I was trying to convert the %column into decimal so I can apply the average function
select
Case WHEN Isnumeric([Percent1]) = 1
THEN CONVERT(DECIMAL(18,2),Replace([Percent1],'%',''))
ELSE 0 END AS Percent1
from DashboardData
but I am just getting 0 values..I am guessing the outer function is running before the inner for some reason. Can someone please tell me how I can achieve this.
I know the IsNumeric function will make it 0 but I tried it before that and I was getting an exception that type is not a number.
Thanks
SELECT ISNUMERIC('3%') will return 0, as will all the rest of your values, so your else condition will always be the result.
Just drop the %
select
data,
(replace(Percent1,'%','') + replace(Percent2,'%','') + replace(Percent3,'%','')) * 1.0 / 3
Note, if any of these values are NULL you need to account for that because NULL + anything IS NULL.
Also, you don't want to lean on ISNUMERIC too heavy... it can produce some results you probably aren't expecting
select
ISNUMERIC('$') --money which is a numeric value
,ISNUMERIC('1e4') --scientific notation
,ISNUMERIC('45D-1') --old scientific notation
,ISNUMERIC('.') --just the decimal portion of a float / decimal
Is this what you want?
select dd.*, s.average
from dashboarddata dd cross apply
(select avg(try_convert(numeric(10, 2), replace(pc, '%', ''))) as average
from values (percent1), (percent2), (percent3)) as v(pc)
) s;

Redshift division result does not include decimals

I'm trying to do something really quite basic to calculate a kind of percentage between two columns in Redshift. However, when I run the query with an example the result is simply zero because the decimals are not being covered.
code:
select 1701 / 84936;
Output:
I tried :
select cast(1701 / 84936 as numeric (10,10));
but the result was 0.0000000000.
How could I solve this silly thing?
It is integer division. Make sure that at least one argument is: NUMERIC(accurate data type)/FLOAT(caution: it's approximate data type):
/ division (integer division truncates the result)
select 1701.0 / 84936;
-- or
SELECT 1.0 * 1701 / 84936;
-- or
SELECT CAST(1701 AS NUMERIC(10,4))/84936;
DBFiddle Demo
When mixing data types the order counts
Note that the order of the elements in a math expression counts for the data type of the result.
Let's assume that we intend to calculate the percentage unit_sales/total_sales where both columns (or numbers) are integers.
See and try with this code here.
-- Some dummy table
drop table if exists sales;
create table sales as
select 3 as unit_sales, 9 as total_sales;
-- The calculations
select
unit_sales/total_sales*100, --> 0 (integer)
unit_sales/total_sales*100.0, --> 0.0 (float)
100.0*unit_sales/total_sales --> 33.3 (float and expected result)
from sales;
The output
0 | 0.0 | 33.33
The first column is 0 (integer) because of 3/9=0 in an integer division.
The second column is 0.0 because SQL first got the integer 0 (3/9), and later, SQL converts it to float in order to perform the multiplication by 100.0.
The expected result.
The non-integer 100.0 at the beginning of the expression force a non-integer calculation.

What is the meaning of <number>d or <number>f in oracle?

Here is the normal execution to select 100 from the dual table:
SQL> select 100 from dual;
100
----------
100
Here is the same execution adding 'a' to the number 100 which just sets the column name. The result will be same for any other alphabets except d and f.
SQL> select 100a from dual;
A
----------
100
Here is the same execution adding 'd' and 'f' to the number 100
SQL> select 100d from dual;
100D
----------
1.0E+002
SQL> select 100f from dual;
100F
----------
1.0E+002
Where is it useful? What does it mean?
d and f are there to implicitly declare the number as a floating-point.
1.0E+002 is the scientific notation for 100
100a is just interpreted by oracle as number value 100 aliased a.
Official doc NUMBER and Floating-Point Literals
f or F indicates that the number is a 32-bit binary floating point
number (of type BINARY_FLOAT).
d or D indicates that the number is a 64-bit binary floating point
number (of type BINARY_DOUBLE)
An example of this behavior can be found in the ROUND() function doc
The following examples illustrate the difference between rounding
NUMBER and floating-point number values. NUMBER values are rounded up
(for positive values), whereas floating-point numbers are rounded
toward the nearest even value:
SELECT ROUND(1.5), ROUND(2.5) FROM DUAL;
ROUND(1.5) ROUND(2.5)
---------- ----------
2 3
SELECT ROUND(1.5f), ROUND(2.5f) FROM DUAL;
ROUND(1.5F) ROUND(2.5F)
----------- -----------
2.0E+000 2.0E+000
Just a guess: the "f"/"F" suffix means floating point (thus, the scientific notation with mantissa and exponent).
"d"/"D" would perhaps be decimal??? (fixed precision decimal)
Google for Oracle Numeric Types, maybe :-(