Extract values from json_array in Athena - hive

I have JSON data as follows:
[{"all":{"end":"22:00","start":"11:00"},"dayOfWeek":1},{"all":{"end":"22:00","start":"11:00"},"dayOfWeek":2},{"all":{"end":"22:00","start":"11:00"},"dayOfWeek":3},{"all":{"end":"22:00","start":"11:00"},"dayOfWeek":4},{"all":{"end":"22:00","start":"11:00"},"dayOfWeek":5},{"all":{"end":"22:00","start":"11:00"},"dayOfWeek":6},{"all":{"end":"22:00","start":"11:00"},"dayOfWeek":7}]
I need to extract values of dayOfWeek, start & end
Tried the solution suggested for Unable to convert varchar to array in Presto Athena but no luck.
Expected Result:
dayOfWeek start end
1 11:00 22:00
2 11:00 22:00
3 11:00 22:00
4 11:00 22:00
5 11:00 22:00
6 11:00 22:00
7 11:00 22:00

You can use the following query. Verified with version 0.172.
WITH data(value) AS (VALUES
'[{"all":{"end":"22:00","start":"11:00"},"dayOfWeek":1},{"all":{"end":"22:00","start":"11:00"},"dayOfWeek":2},{"all":{"end":"22:00","start":"11:00"},"dayOfWeek":3},{"all":{"end":"22:00","start":"11:00"},"dayOfWeek":4},{"all":{"end":"22:00","start":"11:00"},"dayOfWeek":5},{"all":{"end":"22:00","start":"11:00"},"dayOfWeek":6},{"all":{"end":"22:00","start":"11:00"},"dayOfWeek":7}]'
),
parsed(c1) AS (
SELECT cast(json_parse(value) AS array(json))
FROM data
)
SELECT
json_extract_scalar(json1, '$.dayOfWeek') AS "dayOfWeek"
,json_extract_scalar(json1, '$.all.start') AS "start"
,json_extract_scalar(json1, '$.all.end') AS "end"
FROM parsed, unnest(c1) as t(json1)

Related

Generate rows with time intervals between 2 dates in Oracle

I have table in which Sunday to Saturdy "Doctor Start" and "End Time" is given.
I want to create time slots of 15 minutes.
On the basis of that, the patient clicks on calendar datetime interval which shows slots that have already been booked.
The following example shows how to split time into slices of 15 minutes. It uses hierarchical query. A little bit of explanation:
line 2: trunc function, applied to a date value, returns "beginning" of that day (at midnight). Adding 15 / (24*60) adds 15 minutes (as there are 24 hours in a day and 60 minutes in an hour). Multiplying 15 by level works as a "loop", i.e. adds 15-by-15-by-15 ... minutes to previous value.
line 4: similar to line 2, but it makes sure that a day (24 hours * 60 minutes) is divided to 15-minutes parts
line 6: start time is trivial
line 7: end time just adds 15 minutes to start_time
line 9: return only time between 10 and 16 hours (you don't have patients at 02:15 AM, right?)
SQL> with fifteen as
2 (select trunc(sysdate) + (level * 15)/(24*60) c_time
3 from dual
4 connect by level <= (24*60) / 15
5 )
6 select to_char(c_time, 'hh24:mi') start_time,
7 to_char(c_time + 15 / (24 * 60), 'hh24:mi') end_time
8 from fifteen
9 where extract(hour from cast (c_time as timestamp)) between 10 and 15;
START_TIME END_TIME
---------- ----------
10:00 10:15
10:15 10:30
10:30 10:45
10:45 11:00
11:00 11:15
11:15 11:30
11:30 11:45
11:45 12:00
12:00 12:15
12:15 12:30
12:30 12:45
12:45 13:00
13:00 13:15
13:15 13:30
13:30 13:45
13:45 14:00
14:00 14:15
14:15 14:30
14:30 14:45
14:45 15:00
15:00 15:15
15:15 15:30
15:30 15:45
15:45 16:00
24 rows selected.
SQL>

sql missing date query

Having a table with these records:
01-JAN-15 10:00
01-JAN-15 11:00
01-JAN-15 13:00
01-JAN-15 14:00
01-JAN-15 15:00
01-JAN-15 18:00
01-JAN-15 19:00
It's 1h resolution, so in my example 12:00, 16:00 and, 17:00 are missing.
I would like to create an SQL query that returns something like this (missing hour start, and duration):
01-JAN-15 12:00, 01:00
01-JAN)15 16:00, 02:00
Any suggestion?
Assuming your values are datetime values, then you can do something like this:
select t.*,
datediff(hour, datetimecol, next_datetimecol)
from (select t.*,
lead(datetimecol) over (order by datetimecol) as next_datetime
from t
) t
where next_datetimecol is not null and
dateadd(hour, 1, datetimecol) < next_datetimecol;
Depending on your data types and the precision, this might not work exactly. But the idea is basically the same . . . use lead() to get the next value and do some comparisons.

Finding in between which two dates in a column the target date is

Got a table that I am trying to clean up and can't figure out how to find a record where one date falls between two dates in the actual columns
TargetDateTime Location TransferDateTime
01/01/2014 1:00 PM Room 1 01/01/2014 10:00 AM
01/01/2014 1:00 PM Room 2 01/01/2014 12:30 PM
01/01/2014 1:00 PM Room 3 01/01/2014 01:30 PM
01/01/2014 1:00 PM Room 4 01/01/2014 03:00 PM
TransferDateTime marks the time when a person was moved to the room
TargetDateTime marks some event that a person did.
In this example, TargetDateTime is 1:00 PM; therefore the event took place in Room 2 because 1:00 PM falls between 12:30 PM and 1:30 PM.
What would be the best way in SQL to select only that row and ignore the rest?
Thanks a bunch for any suggestions!
Based on your sample data and guessing that you have groups of the same TargetDateTime, the following should do it.
;WITH MyCTE AS
(
SELECT TargetDateTime,
Location,
TransferDateTime
ROW_NUMBER() OVER (PARTITION BY TargetDateTime ORDER BY TransferDateTime) AS rn
FROM TableName
WHERE TransferDateTime >= TargetDateTime
)
SELECT *
FROM MyCTE
WHERE rn = 1

How to count the records per half hour from a period (datetimefrom and datetimeto) field?

I have a table which looks like you can see below:
Id Date ScheduledTimeFrom ScheduledTimeTo ActualTimeFrom ActualTimeTo
1 2013-01-01 1899-12-30 07:00:00 1899-12-30 18:00:00 1899-12-30 07:23:00 1899-12-30 17:15:00
I need to calculate per half hour how many records exists, the output should be like:
Time Actual Count:
7:00 4
7:30 4
8:00 4
8:30 4
9:00 4
9:30 5
10:00 5
10:30 6
11:00 7
11:30 8
12:00 8
12:30 8
13:00 8
13:30 8
14:00 8
14:30 8
15:00 7
15:30 7
16:00 7
16:30 6
17:00 5
17:30 4
18:00 4
I already tried to make a helper table which should hold the times per halfhour. I have joined this helpertable with the table that contains the data and after that I tried to use a group by function but it was not working.
My query was like:
Create table period (timefrom datetime, timeto datetime)
insert into period
select '1899-12-30 07:00:00.000', '1899-12-30 07:30:00.000'
Union all
select '1899-12-30 07:30:00.000', '1899-12-30 08:00:00.000'
select *
from period p left join table1 t on t.ActualTimeFrom < p.timeto and t.ActualTimeTo >=p.timefrom
Grouping this give me no desired result....
Anyone an idea how to come to the result?
P.s. I am using sql server 2005.
After snooping around and testing it on my side, looks like this date function could be the answer:
DATEADD(mi,DATEDIFF(mi,0,YOUR_DATE_COLUMN)/30*30,0)

SQL How Many Employees Are Working, Group By Hour

I have a table, a timetable, with check-in and check-out times of the employees:
ID Date Check-in Check out
1 1-1-2011 11:00 18:00
2 1-1-2011 11:00 19:00
3 1-1-2011 16:00 18:30
4 1-1-2011 17:00 20:00
Now I want to know how many employees are working, every (half) hour.
The result I want to see:
Hour Count
11 2
12 2
13 2
14 2
15 2
16 3
17 3
18 2,5
19 1
Every 'Hour' you must read as 'till the next full hour', ex. 11 -> 11:00 - 12:00
Any ideas?
Build an additional table, called Hours, containing the following data:
h
00:00
00:30
01:00
...
23:30
then, run
Select h as 'hour' ,count(ID) as 'count' from timetable,hours where [Check_in]<=h and h<=[Check_out] group by h