What is the replacement for the T-SQL isnumeric() function in hive 0.10?
http://technet.microsoft.com/en-us/library/ms186272.aspx
There isn't a direct equivalent in HIVE but you can use the cast function.
Casting anything that isn't "numeric" to double will return null and you could use it like this :
select x from table where cast(field as double) is not null
You can check if a number is decimal or not by the below check. This can be given in where clause as well.
select case when abs(x%1)>0 then x else cast(x as bigint) end ;
Related
I want to convert specific data to Hive.
However, functions available in Oracle cannot be used in Hive. How can I solve this?
The applied conversion rule is as follows.
DECODE(TRUE, IS_DATE(TO_CHAR(columnname , 'YYYYMMDD')), 'YYYYMMDD',NULL)
In the case of DECODE, it was confirmed that it could be processed with IF.
But I couldn't find a way to change IS_DATE function and TO_CHAR function.
Oracle does not have an IS_DATE function. Are you sure this is not a user-defined function? If so then you will need to look at the source code and check what it does and duplicate that in Hive.
DECODE(a, b, c, d) can be rewritten as a CASE expression:
CASE WHEN a = b THEN c ELSE d END
So your code (assuming that columnname is a DATE and you are using TO_CHAR to convert it to a string and then IS_DATE checks if it is a valid date, which seems pointless as it will only not be a valid date when columnname is NULL) would convert to:
CASE
WHEN CAST(columnname AS STRING FORMAT 'YYYYMMDD') IS NOT NULL
THEN 'YYYYMMDD'
ELSE NULL
END
or, more simply:
CASE
WHEN columnname IS NOT NULL
THEN 'YYYYMMDD'
ELSE NULL
END
I'm trying to make a select to a bigquery table, but I need to assign a default value to a column if it is null, because next in the process I need the default or the real item_id value, I was trying to use the CASE validation but I'm not pretty sure if I can use this clause for this purpose, and I'm getting the next error:
Expected end of input but got keyword case.
Select
p.item_id CASE WHEN item_id IS NULL THEN 'XXXXX' ELSE item_id END AS item_id,
from items
where -- rest of the query
Any ideas?
try this
Select
IFNULL(p.item_id,'XXXXX') AS item_id,
from items
where -- rest of the query
IFNULL() function in BigQuery
IFNULL(expr, null_result)
Description
If expr is NULL, return null_result. Otherwise, return expr. If expr is not NULL, null_result is not evaluated.
expr and null_result can be any type and must be implicitly coercible to a common supertype. Synonym for COALESCE(expr, null_result).
more details: https://cloud.google.com/bigquery/docs/reference/standard-sql/functions-and-operators#ifnull
Use
isnull(yourcolumn,'')
--or
isnull(yourcolumn,99999999)
and you can put anything between those quotes. If the value is an int that won't work though. You will need to make it some default number, preferably something that would never be used like 9999999999.
I am trying to migrate an oracle DB application to postgres.
I can't seem to find an equivalent of NANVL in postgres. Is there a way to emulate the same ?
From the Oracle manual:
The NANVL function is useful only for floating-point numbers of type BINARY_FLOAT or BINARY_DOUBLE. It instructs Oracle Database to return an alternative value n1 if the input value n2 is NaN (not a number). If n2 is not NaN, then Oracle returns n2.
In Postgres you can compare a numeric value to the special constant 'NaN':
select some_column = 'NaN'
from some_table;
So you can write a function that will implement nanvl():
create function nanvl(p_to_test numeric, p_default numeric)
returns numeric
as
$$
select case
when p_to_test = 'NaN' then p_default
else p_to_test
end;
$$
language sql;
Edit
Of course, a_horse_with_no_name is correct.
Everything is simpler: just a CASE with check on equality to NaN is needed http://sqlfiddle.com/#!17/37528
Everything below is incorrect.
Similar to Jorge Campos advice: rip-off isnumeric from isnumeric() with PostgreSQL
and modify it to:
/* Ripoff https://stackoverflow.com/questions/16195986/isnumeric-with-postgresql */
CREATE OR REPLACE FUNCTION nanvl(text, NUMERIC) RETURNS NUMERIC AS $$
DECLARE x NUMERIC;
BEGIN
x = $1::NUMERIC;
RETURN x;
EXCEPTION WHEN others THEN
RETURN $2;
END;
$$
STRICT
LANGUAGE plpgsql IMMUTABLE;
GO
SQLFiddle: http://sqlfiddle.com/#!17/aee9d/1
How to perform case in an oracle concat function ?
I want to concat number and a letter based on the number. ie if number is more than 1 than i have to append s else not.
I tried below query but its not working.
Select concat(count(*) , if count(*) > 1 then 's' else '')
from tablename
group by columnname;
In Oracle it is better to use || for concatenation, and there's no if but there are case expressions. I will show the solution with || as it is best practice, but if you must use concat you can do it as well. Also, Oracle will convert a number to a VARCHAR2 for you, but it is best to write your conversions explicitly.
select to_char(count(*)) || case when count(*) > 1 then 's' end from ....
NOTE - the default value of case is '' (same as NULL in Oracle), so I didn't need to write more.
In Oracle, usually, SQL functions that should return true/false return 1/0 because the BOOLEAN data type only exists in PL/SQL blocks.
For example with Oracle Text, you must not forget the > 0 in SELECT * FROM bartbl WHERE CONTAINS(foocol, 'sometext') > 0. Otherwise you get ORA-00920 invalid relational operator.
However, it seems that REGEXP_LIKE behaves like a true boolean: you can do SELECT * FROM bartbl WHERE REGEXP_LIKE(foocol, 'sometext') and it works.
So I would like to know why this is the case and if there is a possibility for me to write some functions like this?
Once upon a time, there was no boolean requirement in ANSI SQL (not sure if that requirement exists in latest standards?), and Oracle tends to do their own thing sometimes ;) But, personally I don't see the issue in using Y/N or 1/0.
Anyway, REGEXP_LIKE is really a type of filter (can reduce the number of rows returned), not the same as a typical function (which will return a value (or null) for each row it processes). But good thing is that if you really want to mimic the filter functionality, you can use REGEXP_LIKE with your own function. For example:
create or replace function is_big_number(i_num in number)
return varchar2
as
begin
if (i_num >= 1000000) then
return 'Y';
end if;
return 'N';
end;
with x as (
select 50000 as num from dual
union all
select 1000000 as num from dual
union all
select 3 as num from dual
)
select num, is_big_number(num)
from x
-- this is a filter, not a typical "function"
where
regexp_like(is_big_number(num), 'Y');
Output:
NUM IS_BIG_NUMBER(NUM)
1000000 "Y"
Hope that helps.
Oracle's built in functions are special, you can't write one like this yourself. I don't know why though