Cast bigint to decimal(18,5) in hive - hadoop

I'm trying to cast a bigint to decimal(18,5) in hive and I'm not getting any fraction values after converting to decimal(18,5).
Let's take the below bigint values
99000
999000
499000
350000
344000000
After casting to decimal(18,5), I'm expecting something like below
0.99000
9.99000
4.99000
3.50000
3440.00000
I'm trying the below query.
select col_a, cast(col_a as decimal(18,5)) from table;
From above query, I'm getting output same as input
99000
999000
499000
350000
344000000
Also, I tried dividing the input with 10^5 and casting to decimal(18,5).
select col_a, cast(col_a/100000 as decimal(18,5)) from table;
Above query is returning the fraction values, but not having 5 digits after the decimal.
0.99
9.99
4.99
3.5
344000000
Could someone please correct me what I'm missing or doing wrong here.

DECIMAL type do not permit values larger than the range implied by the column definition.
DECIMAL(5,0) column supports a range of -99999 to 99999.
DECIMAL(M,D) column permits up to M - D digits to the left of the decimal point.
For example DECIMAL(5,2) permits -999.99 to 999.99
And the trailing zeroes are not displayed. If you need them guaranteed to be displayed, use string type and rpad() function to add zeroes at the end or something like that.
If the number cannot be cast to decimal, NULL is returned, for example the following cast returns NULL:
select cast(1234567890L as decimal(3,1))
It is not clear why do you expect cast a bigint to decimal(18,5) to produce some fractional numbers. cast does not divide your initial numbers.

Related

Format mask with leading zero for NUMBER

Which format mask should I use to convert number data from table column NUMBER to char if I want to preserve one leading zero and don't know data "size"? Value could have integral and/or fractional part. All that I know - it's NUMBER.
Source Data (numbers)
.12345678901234567890
100
100.500
12345678901234567890.1234567890
Desired result (text)
0.1234567890123456789
100
100.5
12345678901234567890.123456789
and so on, i.e. number could have unpredictable number of digits in whole part and unpredictable number of digits in fractional part.
A NUMBER data type is a binary value that has no format; if you want to format the number then you will need to convert it to another data-type that can represent the numeric value with a format, such as a VARCHAR2 data-type using the TO_CHAR function:
SELECT value,
RTRIM(
TO_CHAR( value, 'FM999999999999999999999990D99999999999999999999' ),
'.'
) AS formatted_number
FROM table_name
Which, for the sample data:
CREATE TABLE table_name ( value ) AS
SELECT .12345678901234567890 FROM DUAL UNION ALL
SELECT 100 FROM DUAL UNION ALL
SELECT 100.500 FROM DUAL UNION ALL
SELECT 12345678901234567890.1234567890 FROM DUAL
Outputs:
VALUE
FORMATTED_NUMBER
.1234567890123456789
0.1234567890123456789
100
100
100.5
100.5
12345678901234567890.123456789
12345678901234567890.123456789
number could have unpredictable number of digits in whole part and unpredictable number of digits in fractional part.
Just increase the number of 9s before and after the D decimal separator until the number of integer/fractional digits reaches your maximum precision.

Supress leading zeros from oracle table extract to a file

I am extracting data from oracle table to a text file and I have below number columns. When I select the below columns to a file it gives me all leading zeros which I wanted to suppress.
Select ltrim(col_1,'0'),ltrim(col_2,'0'),ltrim(col_3,'0') from table1
Datatype:
Col_1 ---NUMBER(10,2),
Col_2 ---NUMBER(38,0),
Col_3 ---NUMBER(15,1)
Current Output:
00000303.44|0| 00000000000008.2
00000000.00|26| 00000000000030.2
00000473.40|0| 00000000000010.0
Expected Output:
303.44|0|8.2
0|26|30.2
473.4|0|10
Please let me know if i need to change the datatype to get the Expected output. I even tried TO_CHAR(TRIM(LEADING 0 FROM col_name) i did not get the expected output.
This is caused by the datatypes set in the last output stage of your datastage job. When a column is set a decimal, datastage will fill the remaining positions with leading zeros up to the size if your decimal field.
The easiest way to get around this is to place a transform prior to the file output stage and convert all the columns to a varchar at the last stage trimming all the leading zeros.
Since the data is not in number and possibly in varchar/varchar2;
conversion is required; you can use to_number to address this;
Using one of your sample data in below case
select
to_number(00000000000008.2) as num1,
to_number('00000000000008.2') as chr1,
trim(00000000000008.2) as num2,
trim('00000000000008.2') as chr2,
ltrim(00000000000008.2,'0') as num3,
ltrim('00000000000008.2','0') as char3
from dual

What does 'XXXXXX' mean as the second argument to TO_NUMBER? Oracle SQL

CREATE OR REPLACE TRIGGER fund_BIU
BEFORE INSERT OR UPDATE ON fund
FOR EACH ROW
BEGIN
IF INSERTING AND :new.fundid IS NULL THEN
:new.fundid := TO_NUMBER(SYS_GUID(), 'XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX');
END IF;
END;
/
I'm interested the IF statement. What does it mean
:new.fundid := to_number(sys_guid(),'XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX');. To be precise sys_guid(), 'xxxxxxxx' part.
TY
Think of the number 33. Focus on what that means - it's a number, it does not have digits. It can be represented as 3 * 10 + 3 * 1 which is why it has two digits in base 10, both digits equal to 3. But you could also represent it as 33.00. The strings '33' and '33.00' are clearly different (one has two characters, the other has five); but if you want to think of them as representing numbers, they represent the same number - the integer 33. Similarly, +33 and +33.00 represent the same number.
If you input a string like '33' or '+33.00' but you want to get out a number, then you use the function TO_NUMBER(). For example: '+33.00' is a string, but TO_NUMBER('+33.00') is a number, the number 33.
TO_NUMBER() allows you to give a format model, so that Oracle understands how to interpret the string it receives as input.
For example, if you input the string '1101' - is that the number one thousand one hundred one, or is it the number 13, given in binary representation?
Similarly, the number 33 has the string representation '21' in hexadecimal ("in HEX"). TO_NUMBER('21') will output the number 21; but you can tell Oracle that you meant a hexadecimal number, by providing the format model 'XX'. There are two X for two digits, and X is often used to mean "hex". So TO_NUMBER('21', 'XX') will output the number 33, not the number 21.
SYS_GUID() outputs the hexadecimal representation of a very large number. The output is a string. Applying TO_NUMBER() to it, with a format model that indicates it should be interpreted as a hex number, will convert it to an actual number (instead of a string of hex digits).
What SYS_GUID() does is generate a unique 16 byte identifier or key. When applying the TO_NUMBER() function, you are getting the 32 number representation of that key. It is basically a way of generating unique numbers in Oracle.
See SYS_GUID() in Oracle documentation: https://docs.oracle.com/cd/B12037_01/server.101/b10759/functions153.htm

Decimal precision in hive

I want to add the decimal precision to be set for the values
Example:
select 1*1.00000;
output: 1.0
Even tried with cast
select cast(cast(1*1.0000 as double) as decimal(5,2))
output: 1
I want the results to be displayed as 1.000. Is there any way to do so in hive?
Create a table and test it. It works if we give the exact precision value as mentioned in the decimal function.
create table test1_decimal (b decimal (5,3));
INSERT INTO test1_Decimal values(1.000); //This will shrink it to 1 as the total digits is not five.
INSERT INTO test1_Decimal values(123.12345); //This results in NULL as it exceeds the total digits(5).
INSERT INTO test1_Decimal values(12.123); //This will give you exact result as the precision and number of digits fits. Ouputs as 12.123
So if the value matches the decimal function then it displays correctly else it shrinks or converts to NULL.

Oracle 01481. 00000 - "invalid number format model"

This is my query i have used to get the value as money. Nut when concat value getting above exception. The query is
select to_char(b.balance,'9999.'||d.number_of_decimal_places) from balance b, decimal d
Am stuck with this problem.
If you have numeric number_of_decimal_places values like 1, 2, 3 etc. then you are constructing a format model like, for example, '9999.2' instead of '9999.99'.
You can convert that integer value to the format model with rpad or lpad:
select to_char(b.balance,'9999.'||rpad('9', d.number_of_decimal_places, '9'))
from balance b, decimal d
Or for trailing zeros:
select to_char(b.balance,'9999.'||rpad('0', d.number_of_decimal_places, '0'))
from balance b, decimal d
If you have string number_of_decimal_places values like '9', '99', '999' etc. then the concatenation you have will work unless you have an invalid value in one of the rows, which would be any character other than a 9 or a 0.
That includes spaces, which you could have in a varchar2 or char field. Either way you could remove those with trim:
select to_char(b.balance,'9999.'||trim(d.number_of_decimal_places))
from balance b, decimal d
But if you have any other characters then you will need to identify and correct the data in those rows; and even with spaces it would be better to fix the data if it's a varchar2 column.
It would be better to use new-style joins; I haven't changed these examples because it isn't clear if you are doing a cartesian product or have just omitted the join conditions.
If number_of_decimals returns a value like 2 then:
SELECT TO_CHAR( b.balance, RPAD( '9999.', 5 + d.number_of_decimals, '9' ) )
FROM balance b
CROSS JOIN
decimal d
For whatever reason, the concatenation of '9999.'||d.number_of_decimal_places is generating an invalid mask. We can only guess at the actual table values, presence of spaces, or whatever else may be causing issues with what it is doing.
So your solution is to run:
select '9999.'||d.number_of_decimal_places from decimal d
See what the actual format mask is that you are generating, and adjust as necessary.

Resources