HiveSQL IF ELSE STATMENT Conditions Migration From GreenPlum - hive

We have to migrate similar IF ELSE statement from Greenplum to HiveSQL, please help us below statement.
SELECT (date_trunc('month', Z_ops_date::date) - interval '1 month')::date into v_lmtd_FrDate;
SELECT DATE_PART('days' , DATE_TRUNC('month', Z_ops_date::date) - '0 MONTH'::INTERVAL - '1 DAY'::INTERVAL ) INTO v_lmtd_endday;
SELECT DATE_PART('days', Z_ops_date::date + 1) INTO v_cur_day;
if v_cur_day = 1 then
SELECT (DATE_TRUNC('month', Z_ops_date::date) - '0 MONTH'::INTERVAL - '1 DAY'::INTERVAL)::date INTO v_lmtd_ToDate ; -- last day of LMTD
else
if v_lmtd_endday > v_cur_day then
SELECT Z_ops_date::date - substring((select (date_trunc('month',Z_ops_date::date))::date - 1)::character varying,9,10)::integer INTO v_lmtd_ToDate ; -- current day of LMTD
elseif v_lmtd_endday < v_cur_day then
SELECT (DATE_TRUNC('month', Z_ops_date::date) - '0 MONTH'::INTERVAL - '1 DAY'::INTERVAL)::date INTO v_lmtd_ToDate ;-- last day of LMTD
else
SELECT Z_ops_date::date - substring((select (date_trunc('month',Z_ops_date::date))::date - 1)::character varying,9,10)::integer INTO v_lmtd_ToDate ; -- current day of LMTD
end if;
end if;
above that condition will be applied as below query.
SELECT Z_ops_date ,extract(year from Z_ops_date) as Year,extract(month from Z_ops_date) as Month ,service_ID,service_type ,sum(fee_amt_day) as fee_amt_day
,v_lmtd_FrDate , v_lmtd_ToDate
FROM test.sampletable
WHERE data_date BETWEEN v_lmtd_FrDate AND v_lmtd_ToDate
GROUP BY service_ID,service_type ;

Related

GreenPlum SQL query to convert into Hive

Below query we want to convert greeenplum SQL to hive sql, kindly help us.
GP sub query :
select a.region , amount_fr , count_fr , amount_sr , count_sr from (
select region , sum(cast(amount as integer)) as amount_fr , count(transid) as count_fr from test.test_fr_imi
where cast(trans_date as date) between (select cast(add_months(trunc(date_sub(cast(current_date as date),1),'MM'),-1) as date) ) and
(select current_date::date - 1 - substring((select (date_trunc('month',current_date::date ))::date - 1)::character varying,9,10)::integer)
group by 1 ) a
JOIN
(select region , sum(amount::integer) as amount_sr , count(transid) as count_sr from test.test_sr_imi
where trans_date::date between (select (date_trunc('month',current_date::date - 1) - interval '1 month')::date) and
(select current_date::date - 1 - substring((select (date_trunc('month',current_date::date ))::date - 1)::character varying,9,10)::integer) group by 1 ) b on
a.region = b.region;
I needs to convert above query which is sub query not able to convert to hive, please find particular code as above one.
(select current_date::date - 1 - substring((select
(date_trunc('month',current_date::date ))::date - 1)::character
varying,9,10)::integer)
select to_char(round((select sum(revenue)/1000000.00 from test.sampletable where trxn_date = current_date-1)/1, 2) ,'999,999')
select to_char(round((select sum(case when to_char(trxn_date, 'yyyymm') = to_char((current_date - 1) - '1 month'::interval, 'yyyymm') and extract(day from trxn_date) < extract(day from current_date) then revenue end)/1000000.00 from test.sample2table)/1, 2) ,'999,999')
select to_char(round ((select(( ( sum(case when to_char(trxn_date, 'yyyymm') = to_char((current_date - 1), 'yyyymm') then revenue end)) - (sum(case when to_char(trxn_date, 'yyyymm') = to_char((current_date - 1) - '1 month'::interval, 'yyyymm') and extract(day from trxn_date) < extract(day from current_date) then revenue end) )) / (sum(case when to_char(trxn_date, 'yyyymm') = to_char((current_date - 1) - '1 month'::interval, 'yyyymm') and extract(day from trxn_date) < extract(day from current_date) then revenue end) ))*100.00 from test.sample3table)/1, 2) ,'9990.99%')
Here are some helps on some functions -
round() - available in hive.
to_char(INT,'999,999') - You can use format_number(12345,0) - this will result 12,345
CURRENT_DATE- available in hive.
CURRENT_DATE-1 - This can be done using current_date - interval '1' day.
Syntax in hive is a little different. You need to put your sql in a subquery adn the calculate on top of it.
So, here is equivalent of first sql-
SELECT format_number(round(sum_rev/1, 2), 0)
FROM
(SELECT sum(revenue)/1000000.00 as sum_rev
FROM test.sampletable
WHERE trxn_date = CURRENT_DATE- interval '1' day) rs
here is equivalent sql of second query
SELECT format_number(round(sum_rev/1, 2), 0)
FROM (SELECT sum(CASE
WHEN from_timestamp(trxn_date, 'yyyyMM') = from_timestamp((CURRENT_DATE - interval '1' day) - interval '1' month, 'yyyyMM')
AND extract(DAY
FROM trxn_date) < extract(DAY
FROM CURRENT_DATE) THEN revenue
END)/1000000.00 as sum_rev
FROM test.sample2table) rs

SQL Conditional Select Help (Amazon Redshift SQL)

I currently have 2 queries that I am trying to merge into 1. Basically I want to pull previous days sales if it's Tuesday - Friday and the previous 3 days sales if it's Monday. My queries are below - is there a way to do a conditional select for those date based on the day of the week?
Monday's version
SELECT *
FROM A
WHEN DATE_TRUNC('day', timestamp) IN (CURRENT_DATE - 1, CURRENT_DATE - 2, CURRENT_DATE - 3)
AND DATE_PART(weekday, current_date) = 1
Tuesday - Friday version
SELECT *
FROM A
WHEN DATE_TRUNC('day', timestamp) = CURRENT_DATE - 1
AND DATE_PART(weekday, current_date) = 1
one solution is :
SELECT *
FROM A
WHERE DATE_TRUNC('date', timestamp) <= DATE_TRUNC('date', CURRENT_DATE)
AND DATE_TRUNC('date', timestamp) >= case when DATE_TRUNC('day of week',CURRENT_DATE) = 'Monday' then DATE_TRUNC('date', CURRENT_DATE - 3) else DATE_TRUNC('date',CURRENT_DATE) end
You can use `OR:
SELECT *
FROM A
WHERE (DATE_TRUNC('day', timestamp) IN (CURRENT_DATE - 1, CURRENT_DATE - 2, CURRENT_DATE - 3) AND
DATE_PART(weekday, current_date) = 1
) OR
(DATE_TRUNC('day', timestamp) = CURRENT_DATE - 1 AND
DATE_PART(weekday, current_date) <> 1
)
This can be slightly simplified to:
WHERE timestamp > CURRENT_DATE -
(CASE WHEN DATE_PART(weekday, current_date) = 1 INTERVAL '3 DAY'
ELSE INTERVAL '1 DAY'
END)
Note: This assumes that there are no future timestamps.

Set-returning functions are not allowed in CASE in postgreSQL

I am trying to run this query was able to till some time ago. I don't know what went wrong and I started getting this error now?
Your database returned: ERROR: set-returning functions are not allowed in CASE Hint: You might be able to move the set-returning function into a LATERAL FROM item.
My query:
SELECT distinct
(CASE
WHEN {PERIOD} = 'Previous Quarter' AND pto.pto_start_date < (date_trunc('quarter', now() - INTERVAL '1 month') + INTERVAL '1 month')::date AND pto.pto_end_date >= (date_trunc('quarter', now() - INTERVAL '1 month') + INTERVAL '1 month')::date
THEN generate_series(pto.pto_start_date, pto.pto_end_date, '2 day'::interval)
WHEN {PERIOD} = 'Current Quarter' AND pto.pto_start_date < (date_trunc('quarter', now() - INTERVAL '1 month') + INTERVAL '1 month')::date AND pto.pto_end_date >= (date_trunc('quarter', now() - INTERVAL '1 month') + INTERVAL '1 month')::date
THEN generate_series(pto.pto_start_date, pto.pto_end_date, '1 day'::interval)
ELSE
generate_series(pto.pto_start_date, pto.pto_end_date, '1 day'::interval)
END) AS dt
FROM cust_pto pto
Start dates and end Dates:
What has gone wrong?
Why you're getting the error now: you upgraded to postgres 10. Set returning functions are no longer allowed.
What to do: there is more than one way to accomplish what you're trying to do. For the sake of keeping it as close as possible to your original query, all you have to do is put your CASE statement inside generate_series:
SELECT distinct generate_series(
pto.pto_start_date,
pto.pto_end_date,
CASE
WHEN {PERIOD} = 'Previous Quarter' AND pto.pto_start_date < (date_trunc('quarter', now() - INTERVAL '1 month') + INTERVAL '1 month')::date AND pto.pto_end_date >= (date_trunc('quarter', now() - INTERVAL '1 month') + INTERVAL '1 month')::date THEN
'2 day'::interval
ELSE
'1 day'::interval
END
) AS dt
FROM cust_pto pto

PostgreSQL querying the current week's data

I'm trying to grab all the appointments that have been booked for this current week I initially tried this:
select *
from appointments
where staff_id = 'id'
and (to_timestamp(appointments.start_time)) > (current_date - interval '1 week')
and (to_timestamp(appointments.start_time)) < (current_date + interval '1 week')
This just selects all the appointments that equal +/- 7 days, so not the current week. This was my next try. I know its broken but I think it gets the point across.
select *
from appointments
where staff_id = 'id'
and (to_timestamp(appointments.start_time)) > (current_date - interval concat(extract(dow from current_date), ' days'))
and (to_timestamp(appointments.start_time)) < (current_date + interval concat(7 - extract(dow from current_date), ' days'))
How would I go about building this query?
If you agree with Postgres's definition of a week, then you can do:
select a.*
from appointments a
where staff_id = 'id' and
to_timestamp(appointments.start_time) >= date_trunc('week', current_date) and
to_timestamp(appointments.start_time) < date_trunc('week', current_date) + interval '1 week';

Converting Recursive Query from Week over Week to Month over Month

I have a recursive query that provides the number of orders placed week over week (week_no, week_start, and week_end). I'd like to create a similar breakdown for a month over month analysis.
WITH recursive weeks (week_start, week_end, time_end, weekno) AS (
VALUES ('2015-12-27'::date, '2016-01-02'::date, '2016-04-02'::date, 1)
UNION ALL
SELECT (week_end + interval '1 day')::date,
(CASE
WHEN (week_end + interval '7 days')::date > time_end THEN time_end
ELSE (week_end + interval '7 days')::date
END)::date,
time_end,
weekno+1
FROM weeks
WHERE time_end > week_end)
Any help would be greatly appreciated.
Why would you use a recursive query for this? Use generate_series():
select g.week_start, g.week_start + interval '6 day' as week_end,
row_number() over (order by g.week_start) as weeknum
from generate_series('2015-12-27'::timestamp,
'2016-01-02'::timestamp,
interval '1 week'
) g(week_start);
The equivalent for months would be like:
select g.month_start, g.month_start + interval '1 month' - interval '1 day' as month_end,
row_number() over (order by g.month_start) as monthnum
from generate_series('2015-12-01'::timestamp,
'2016-01-01'::timestamp,
interval '1 month'
) g(month_start);