how to convert the variety customized time stamp to second in hive - time

I am looking for a solution for my issue. My issue is I want to convert my data to seconds. The data in my HIVE table looks below:
My input:
1 Day 8 Hours 48 Minutes
1 Hour 1 Minutes
3 Hours
20 Minutes
20 Minutes 4 Seconds
50 Seconds
My Expected Output in sec
118080
3660
10800
1200
1204
50

Using regex you can parse all possible templates in a case statement. Maybe this can be optimized, I hope you got the idea. Add more templates and test like this:
with mytable as(
select stack(6,
'1 Day 8 Hours 48 Minutes',
'1 Hour 1 Minutes',
'3 Hours',
'20 Minutes',
'20 Minutes 4 Seconds',
'50 Seconds'
) as mytimestamp
)
select mytimestamp, ts[0]*86400 --days
+ts[1]*3600 --hours
+ts[2]*60 --minutes
+ts[3] --seconds
as seconds
from
(
select mytimestamp,
split(
case when mytimestamp rlike '^(\\d{1,2})\\s(?:Days?)\\s(\\d{1,2})\\s(?:Hours?)\\s(\\d{1,2})\\s(?:Minutes?)$' --Days Hours Minutes
then regexp_replace(mytimestamp,'^(\\d{1,2})\\s(?:Days?)\\s(\\d{1,2})\\s(?:Hours?)\\s(\\d{1,2})\\s(?:Minutes?)$','$1:$2:$3:0')
when mytimestamp rlike '^(\\d{1,2})\\s(?:Hours?)\\s(\\d{1,2})\\s(?:Minutes?)$' --Hours Minutes
then regexp_replace(mytimestamp,'^(\\d{1,2})\\s(?:Hours?)\\s(\\d{1,2})\\s(?:Minutes?)$','0:$1:$2:0')
when mytimestamp rlike '^(\\d{1,2})\\s(?:Hours?)$' --Hours
then regexp_replace(mytimestamp,'^(\\d{1,2})\\s(?:Hours?)$','0:$1:0:0')
when mytimestamp rlike '^(\\d{1,2})\\s(?:Minutes?)$' --Minutes
then regexp_replace(mytimestamp,'^(\\d{1,2})\\s(?:Minutes?)$','0:0:$1:0')
when mytimestamp rlike '^(\\d{1,2})\\s(?:Minutes?)\\s(\\d{1,2})\\s(?:Seconds?)$' --Minutes Seconds
then regexp_replace(mytimestamp,'^(\\d{1,2})\\s(?:Minutes?)\\s(\\d{1,2})\\s(?:Seconds?)$','0:0:$1:$2')
when mytimestamp rlike '^(\\d{1,2})\\s(?:Seconds?)$' --Seconds
then regexp_replace(mytimestamp,'^(\\d{1,2})\\s(?:Seconds?)$','0:0:0:$1')
end,':') as ts
from mytable
)s
Returns:
mytimestamp seconds
1 Day 8 Hours 48 Minutes 118080
1 Hour 1 Minutes 3660
3 Hours 10800
20 Minutes 1200
20 Minutes 4 Seconds 1204
50 Seconds 50

Related

Make 5 minute data to quarter data as first row

I would like to make 5 minute data of each row into quarter data where the first column shows the text of the first 5 minutes and the second column the sum of the first three 5-minute columns. Like this:
29-8-2018 00:00:00 1
29-8-2018 00:05:00 3
29-8-2018 00:10:00 5
29-8-2018 00:15:00 7
29-8-2018 00:20:00 9
29-8-2018 00:25:00 11
To
29-8-2018 00:00:00 9
29-8-2018 00:15:00 27
Thanks in advance,
Allard
Something like this on SQL Server:
select dateadd(minute, -datepart(minute, tm) % 15)), sum(val)
from T t
group by dateadd(minute, -datepart(minute, tm) % 15));
This does assume there are never any seconds to strip off.

Oracle subtracting days and minutes

I want to subtract "X" days and "X" minutes from sysdate, where the days and minutes are an integer as input parameter. For instance, 10 days and 5 minutes.
I found many examples to subtract either minutes or hours but not a combination of days and minutes.
select sysdate - 5 / 24 / 60 from dual -- will retrieve sysdate minus 5 minutes.
--What about the days?
Thank you!
Use an interval literal:
SELECT SYSDATE - INTERVAL '10 00:05' DAY(2) TO MINUTE
FROM DUAL
Or:
SELECT SYSDATE - INTERVAL '10' DAY - INTERVAL '5' MINUTE
FROM DUAL
Or just use arithmetic:
SELECT SYSDATE - 10 /* Days */ - 5 / 24 /60 /* Minutes */
FROM DUAL
Or use NUMTODSINTERVAL:
SELECT SYSDATE - NUMTODSINTERVAL( 10, 'DAY' ) - NUMTODSINTERVAL( 5, 'MINUTE' )
FROM DUAL
You can use Interval day to minute - http://docs.oracle.com/cd/B19306_01/server.102/b14200/sql_elements003.htm#i38598
select sysdate - interval '1 00:05' day to minute from dual

Adding an interval of 1 calendar month to a date

I would like to add 1 calendar month to a date, ignoring number of days in the month. i.e. add_month('2015-02-23') returns 2015-03-23 and add_month('2015-05-23') returns 2015-06-23
It seems like I could use INTERVAL '1 month' to do this, but I was surprised to find that whenever I do this, it adds 30 days to my input i.e. functionally the same as INTERVAL '30 days'. Does this happen for you too? What should I do instead to increment by 1 calendar month?
Examples:
SELECT DATE('2015-04-23') + INTERVAL '1 month'
returns 2015-05-23
while
SELECT DATE('2015-05-23') + INTERVAL '1 month'
returns 2015-06-22!
This behavior is due to Vertica being modeled on SQL 2008 in which 1 MONTH is a static 30 days, not a "smart month."
dbadmin=> SELECT INTERVAL '1 MONTH';
?column?
----------
30
(1 row)
In order to get the desired behavior, you should use INTERVALYM:
dbadmin=> SELECT INTERVALYM '1 MONTH';
?column?
----------
0-1
(1 row)
dbadmin=> SELECT DATE('2015-05-23') + INTERVALYM '1 MONTH';
?column?
---------------------
2015-06-23 00:00:00
(1 row)
Read more

Partition in a sql query, selecting only previous rows without the current one

Let's assume that I have the next table (sales) with the information of sales for a city in a particular month:
month 7 8 9 10
city a 10 20 30 40
If I decide to execute the next query:
select city, month,
avg(sales) over (partition by city order by month rows 2 preceding) as avg
from sales
I will have the next result
month 7 8 9 10
city a 10 20 30 40
avg 10 10 20 30
This query will take the previous 2 months and the current one, but I will like to have the calculation only with the two previous months without the current one, something like this:
avg 10 10 15 25
Is there a way to do this?
. Is there a way to do this?
It should be this one
select city, month,
avg(sales) over (partition by city order by month rows between 2 preceding and 1 preceding) as avg
from sales
or you can work even with INTERVAL instead of physical rows.
select city, month,
avg(sales) over (partition by city order by month RANGE between NUMTOYMINTERVAL(2,'MONTH') preceding and NUMTOYMINTERVAL(1,'MONTH') preceding) as avg
from sales

Convert interval to minutes

Let's suppose I have 2 intervals:
INTERVAL '0 00:30:00' DAY TO SECOND
INTERVAL '0 04:00:00' DAY TO SECOND
What is the most elegant way to get amount of minutes in each interval. 30 and 240 accordingly.
Yes, I know I can perform EXTRACT(HOUR FROM interval) * 60 + EXTRACT(MINUTE FROM interval), but this looks terrible to me.
Any better solutions?
What looks terrible to you, looks perfectly acceptable to me. If you look at the documentation at the arithmetic you can perform on INTERVALs:
http://download.oracle.com/docs/cd/E11882_01/server.112/e17118/sql_elements001.htm#sthref175
then you see you can multiply them with numerics. So if you multiply your intervals to 24 and 60, you can get the number of minutes by extracting the number of days. It's more compact, but I doubt if it's more elegant in your view.
SQL> create table t (my_interval interval day to second)
2 /
Table created.
SQL> insert into t
2 select numtodsinterval(30,'minute') from dual union all
3 select numtodsinterval(4,'hour') from dual
4 /
2 rows created.
SQL> select my_interval
2 , 60 * extract(hour from my_interval)
3 + extract(minute from my_interval) minutes_terrible_way
4 , extract(day from 24*60*my_interval) minutes_other_way
5 from t
6 /
MY_INTERVAL MINUTES_TERRIBLE_WAY MINUTES_OTHER_WAY
------------------------------ -------------------- -----------------
+00 00:30:00.000000 30 30
+00 04:00:00.000000 240 240
2 rows selected.
Regards,
Rob.
(extract(day from my_interval) * 24 * 60 + extract(hour from my_interval)) * 60 + extract(minute from my_interval) my_way
Don't forget about days.
Reusing Rob's example above,
select (sysdate-(sysdate-to_dsinterval(my_interval)))*24*60 from t;

Resources