hive/impala - inserted decimal showed as null - impala

I created table as
create table test ( x decimal(5,2))
then I tried to insert a value
insert into test values ( cast( 1000.2 as decimal(5,2) ) );
insert into test values ( cast('2000.3' as decimal(5,2) ) );
insert into test values ( cast('3000,4' as decimal(5,2) ) );
but in the end select * from test; is returning 3x NULL value.
What I'm doing wrong ? I can't believe any of above mentioned statements doesn't work.
I'm using impala at recent Cloudera quickstart VM.

Precision is the number of digits in a number. Scale is the number of digits to the right of the decimal point in a number. For example, the number 123.45 has a precision of 5 and a scale of 2
select cast(1000.2 as decimal(5,1)) as a,
cast(1000.2 as decimal(5,2)) as b,
cast(1000.2 as decimal(6,2)) as c
will give you
a 1000.2
b NULL
c 1000.2

Related

SQL query should return percentage but returns error

I have the following lines of code:
ROUND((((SUM(VALOR_2)) - SQLTMP.VALOR_1) / SQLTMP.VALOR_1) * 100, 2)
I was hoping it would return a percentage, but it returns an ERROR instead... Any ideas on what's wrong?
Depending on your inputs you can try addapting this solution :
CREATE TABLE #TMP (
val1 int,
val2 int
);
INSERT INTO #TMP
VALUES (1,2),(1,3),(1,4),(2,5),(2,6)
GO
-- Your code begins here
WITH tmp_table AS (
SELECT
val1 AS val1,
SUM(COLAESCE(val2, 0)) AS sum_val2
FROM #TMP
GROUP BY val1,val2
)
SELECT ROUND((sum_val2 - val1)/val1,2) FROM tmp_table;
-- Your code ends here
GO
DROP TABLE #TMP
select
round(v1/(v2*1.0), 2) as pct
from table
-- multiplying by 1.0 converts the int to decimal, round limits it to 2 places.

Getting 0 instead of decimal when dividing a int by 100 in SQL

I have a column Column1 of an int type in myTable with a value of, let's say, 25.
When inserting cast(Column1 as decimal)/100 into a temp table #tempTbl as following
create table #tempTbl
(
Column1 decimal
)
Insert into #tempTbl
select cast(Column1 as decimal)/100
from myTable
I see 0 in the Column1 of a temp table instead of 0.25
When I try select cast(25 as decimal)/100, I'm getting 0.25
What am I doing wrong?
I would suggest:
select Column1 / 100.0
SQL Server does integer division (as you have discovered). Just including a decimal place in a constant or multiplying by 1.0 usually resolves the issue.
Try
select cast(Column1 as decimal)/100.0
If execute
select 25/100.0;
It returns
(No column name)
0.250000
Please see this code. The decimel length was specified in the DDL of the temp table
create table #tempTbl
(
Column1 decimal(8,2)
)
Insert into #tempTbl
select 25
select Column1/100.0 from #tempTbl;
Output
0.2500000

Show data where the value is after the decimal point

I would like to do (select value from table where...) where the value of a given experiment is not an integer, but it is decimal
You can use FLOOR function to do this. It will round up your numbers, so you can pick only this that are not integers.
create table #t (i decimal(12,6))
insert into #t values (1), (1.1)
select * from #t where FLOOR(i) <> i
You can do as
CREATE TABLE T( Val DECIMAL(10, 2));
INSERT INTO T VALUES
(10.10), (10);
SELECT *
FROM T
WHERE CAST(Val AS INT) <> Val
Returns: 10.10

Decimal place in select statement sql

I have a perfectly working select statement which I have been using. However I have noticed that it does not return any more than zero decimal places. Which I thought Excel had been factoring out, when copied across, but its not.
I have tried to change the format, but I still get zero decimal places. I have reviewed all posts on here, but as I am using a Case statement as well it is not simple to include.
Round(AVG(case when [Duration] > 0 then [Duration] end), 3) as AVGLOS,
Any help welcomed as always.
Data type is an int
That is your problem.
The avg of integer values is always integer:
declare #t table (col int);
insert into #t values (2), (3);
select avg(col)
from #t;
----
2
So you should manipulate decimals, not integers like this:
declare #t table (col int);
insert into #t values (2), (3);
select avg(col * 1.)
from #t;
---
2.500000
So in your case just use this:
Round(AVG(case when [Duration] > 0 then [Duration]* 1. end), 3) as AVGLOS

SQL Server window function for running percentage

I know there are several examples of recursion with CTE and so on, but how can this be accomplished just by using window functions in SQL Server 2012:
CREATE TABLE #temp
(
ID INT PRIMARY KEY IDENTITY(1,1) NOT NULL,
Percentage INT NOT NULL
)
DECLARE #Calculated MONEY = 1000
INSERT INTO #temp ( Percentage ) VALUES ( 100 )
INSERT INTO #temp ( Percentage ) VALUES ( 90)
INSERT INTO #temp ( Percentage ) VALUES ( 60)
INSERT INTO #temp ( Percentage ) VALUES ( 50)
INSERT INTO #temp ( Percentage ) VALUES ( 100)
And the result would be a running percentage like so (we are starting with $1000)
id percentage calculated
-- -------- ---------
1 100 1000
2 50 500
3 90 450
4 80 360
5 100 360
So the value for the next row is the percentage multiplied by the calculated value above that row. Can LAG be used on a computed alias?
Thanks,
You need a running product of the percentages instead of always comparing 2 consecutive rows, which is why LEAD and LAG won't work here.
You can use a windowed sum to keep a running product of the percentages against your variable to get your desired calculation:
SELECT
ID,
Expected,
EXP(SUM(LOG(CONVERT(FLOAT, Percentage) / 100)) OVER (ORDER BY ID)) * #Calculated AS Actual
FROM #Temp
Adding this to your sample code (with a column I added for your expected output):
CREATE TABLE #temp
(
ID INT PRIMARY KEY IDENTITY(1,1) NOT NULL,
Percentage INT NOT NULL,
Expected MONEY NOT NULL
)
DECLARE #Calculated MONEY = 1000
INSERT INTO #temp ( Percentage, Expected ) VALUES ( 100 , 1000)
INSERT INTO #temp ( Percentage, Expected ) VALUES ( 50, 500)
INSERT INTO #temp ( Percentage, Expected ) VALUES ( 90, 450)
INSERT INTO #temp ( Percentage, Expected ) VALUES ( 80, 360)
INSERT INTO #temp ( Percentage, Expected ) VALUES ( 100, 360)
SELECT
ID,
Expected,
EXP(SUM(LOG(CONVERT(FLOAT, Percentage) / 100)) OVER (ORDER BY ID)) * #Calculated AS Actual
FROM #Temp
This will yield your expected output:
ID Expected Actual
----------- --------------------- ----------------------
1 1000.00 1000
2 500.00 500
3 450.00 450
4 360.00 360
5 360.00 360
you can use recursive cte to get the desired result
with cte
as
(
select id, percentage, 1000 as calculated
from #temp
where id =1
union all
select t.id, t.percentage, t.percentage*cte.calculated/100 as calculated
from #temp t
join cte
on t.id = cte.id+1
)
select * from cte
I'm afraid, widow functions won't help here (at least they won't make it simple). The easiest way to achieve your goal is update statement with double assignment:
alter table #temp add VAL decimal
declare #val decimal = 1000
update t set
#val = VAL = #val * Percentage / 100
from (select top 100 percent * from #temp order by id) as t
select * from #temp