How to group by hour in HANA - sql

I have the following table in HANA :
vehicle_id time roaming_time parking_time
1 Sep 01,2016 3:09:03 AM 3 9
2 Sep 01,2016 3:12:03 AM 6 8
1 Sep 01,2016 9:10:03 AM 10 6
4 Sep 01,2016 10:09:03 AM 9 3
1 Sep 01,2016 10:10:03 AM 10 10
4 Sep 01,2016 12:09:03 AM 3 9
from these information I wanted to know that what is the sum of roaming_time and sum of parking_time for each hour from all the vehicles and want the output in the format:
time roaming_time parking_time
____ _____________ ____________
2016-09-01 00:00:00 3 9
2016-09-01 01:00:00 6 8
2016-09-01 02:00:00 9 6
2016-09-01 03:00:00 3 6
2016-09-01 04:00:00 12 3
2016-09-01 05:00:00 15 8
2016-09-01 06:00:00 18 4
2016-09-01 07:00:00 8 3
2016-09-01 08:00:00 9 4
2016-09-01 09:00:00 6 6
2016-09-01 10:00:00 6 9
........
2016-09-01 23:00:00 3 12
I need to group the following query which gives all the sum by hour wise and get the expected result:
select sum(roaming_time) as roaming_time,sum(parking_time) as parking_time
from time>='2016-09-01 00:00:00'
time>='2016-09-01 23:59:59'
I do not know how to do the grouping by hour in HANA. Any help is appreciated

Here is one method . . . it converts the time to a date and hour format:
select to_varchar(time, 'YYYY-MM-DD'), hour(time),
sum(roaming_time) as roaming_time, sum(parking_time) as parking_time from t
group by date(time), hour(time)
order by to_varchar(time, 'YYYY-MM-DD'), hour(time);

Use a group by clause with SERIES_ROUND(). Avoid date() and hour() and similar data/time functions on large data sets as they tend to be slower.
select SERIES_ROUND(time, 'INTERVAL 1 HOUR') as time,
sum(roaming_time) as roaming_time, sum(parking_time) as parking_time from t
group by SERIES_ROUND(time, 'INTERVAL 1 HOUR')
order by SERIES_ROUND(time, 'INTERVAL 1 HOUR');

Another approach is to convert it to a string, especially if no further time calculations are required.
This could look like this:
select to_varchar(time, 'DD.MM.YYYY HH24') as parking_hour ,
sum(roaming_time) as roaming_time, sum(parking_time) as parking_time from t
group by to_varchar(time, 'DD.MM.YYYY HH24') as parking_hour
order byto_varchar(time, 'DD.MM.YYYY HH24') as parking_hour;

Related

How can i create a new column count in SQL table where count=1 if hours column >=6 else count=0

I aim to first achieve this
id
employee
Datelog
TimeIn
TimeOut
Hours
Count
5
Two
2022-08-10
09:00:00
16:00:00
07:00:00
1
4
Two
2022-08-09
09:00:00
16:00:00
07:00:00
1
3
Two
2022-08-08
09:00:00
16:00:00
07:00:00
1
2
One
2022-08-05
09:00:00
16:00:00
07:00:00
1
1
Two
2022-08-04
09:00:00
10:00:00
01:00:00
0
and now my main objective here is to give a bonus of 2k to employees whose Totalcount per month >=3.
employee
Month
TotalCount
Bonus
Two
August
3
2000
One
August
1
0
Here's the answer using Postgres. It's pretty much generic other than extracting the month out of datelog that might have a slightly different syntax.
select employee
,max(date_part('month', datelog ))
,count(*)
,case when count(*) >= 3 then 2000 else 0 end as bonus
from t
where hours >= time '06:00:00'
group by employee
employee
max
count
bonus
Two
8
3
2000
One
8
1
0
Fiddle

How do I retrieve data in Monday to Friday Hourly Format

I have a table that is currently in the following format
ID
Title
CreatedOn
1
Test 1
2021-04-26 08:00:00
2
Test 2
2021-04-26 10:00:00
3
Test 3
2021-04-27 09:00:00
4
Test 4
2021-04-28 14:00:00
5
Test 5
2021-04-28 16:00:00
6
Test 6
2021-04-28 12:00:00
7
Test 7
2021-04-29 13:00:00
8
Test 8
2021-04-30 06:00:00
9
Test 9
2021-05-17 10:00:00
10
Test 10
2021-05-18 19:00:00
11
Test 11
2021-05-18 23:00:00
12
Test 12
2021-05-19 16:00:00
13
Test 13
2021-05-20 07:00:00
14
Test 14
2021-05-21 14:00:00
15
Test 15
2021-05-21 10:00:00
16
Test 16
2021-04-30 10:00:00
What I would like to do is a query that would tell me how many requests have been Monday to Friday per hour. So aggregate all the data into just rows of Monday to Friday.
So the query should return
Day
Hour
Count
Monday
08:00
1
Monday
10:00
2
Tuesday
10:00
1
Tuesday
19:00
1
Tuesday
23:00
1
Wednesday
14:00
1
Wednesday
16:00
2
Wednesday
12:00
1
etc.. How do I achieve this?
So far I have the following
SELECT
DATENAME(WEEK, CreatedOn) AS Week,
DATEPART(Hour, CreatedOn) AS Hour,
COUNT(*) AS Requests
FROM [Enterprise32].[dbo].[nav_EmailEstimateRequests]
where CreatedOn > '2021-01-01'
GROUP BY DATENAME(WK, CreatedOn),DATEPART(Hour, CreatedOn)
ORDER BY DATENAME(WK, CreatedOn);
But the above query returns each week so Week 1 up until Week 21. Please guide me in the right direction.
Thank you!
You want weekday for the date part:
SELECT DATENAME(WEEKDAY, CreatedOn) AS Weekday,
DATEPART(Hour, CreatedOn) AS Hour,
COUNT(*) AS Requests
FROM [Enterprise32].[dbo].[nav_EmailEstimateRequests]
WHERE CreatedOn > '2021-01-01'
GROUP BY DATENAME(WEEKDAY, CreatedOn), DATEPART(Hour, CreatedOn), DATEPART(WEEKDAY, CreatedOn)
ORDER BY DATEPART(WEEKDAY, CreatedOn), Hour;
Note: I included DATEPART(weekday, ) in the GROUP BY, so you could use it in the ORDER BY.

Multiplying a timestamp data for several times in BigQuery [duplicate]

This question already has answers here:
Is there a SQL function to expand table?
(4 answers)
Closed 3 years ago.
I have a time-series starting from 2017-01-01 00:00:00 to the end of 2017-12-31 23:00:00 for 1-hour interval. I need to duplicate this 1-year timestamp for 2400 times in the same column. I need help about this one..
Row Date_time
1 2017-01-01 00:00:00 UTC
2 2017-01-01 01:00:00 UTC
3 2017-01-01 02:00:00 UTC
4 2017-01-01 03:00:00 UTC
5 2017-01-01 04:00:00 UTC
6 2017-01-01 05:00:00 UTC
7 2017-01-01 06:00:00 UTC
8 2017-01-01 07:00:00 UTC
...........................
...........................
You would do this in BigQuery by generating a timestamp array and then unnesting:
select ts
from unnest(generate_timestamp_array('2017-01-01 00:00:00', '2017-12-31 23:00:00', interval 1 hour)) ts
You can then get multiple rows with a similar construct:
select ts
from unnest(generate_timestamp_array('2017-01-01 00:00:00', '2017-12-31 23:00:00', interval 1 hour)
) ts cross join
unnest(generate_series(1, 2400)) n

Select data where days between two dates are part of a given month

My data looks like below, and I need to show the ids where interval between date1 and date2 are part of a given month/year parameter.
Eg.: for July 2018 I need ids from 1 to 7.
date1 date2 id
---------- ---------- --------
2017-11-01 2018-08-28 1
2018-06-05 2018-07-05 2
2018-06-05 2019-05-07 3
2018-06-05 2018-08-08 4
2018-07-01 2018-07-31 5
2018-07-07 2018-07-15 6
2018-07-27 2018-08-05 7
2018-06-01 2018-06-07 8
2018-08-03 2018-09-01 9
solution is quite simple
SELECT
id
FROM
YOUR_TABLE
WHERE
date1<=YOUR_DATE_END_OF_MONTH AND date2>=YOUR_DATE_START_OF_MONTH
e.g. for July 2018
SELECT
id
FROM
YOUR_TABLE
WHERE
date1<='2018-07-31' AND date2>='2018-07-01'
or if you do not need to calculate first end day of the month (but this do not use any indexes if exists on date1 and date2)
SELECT
id
FROM
YOUR_TABLE
WHERE
EXTRACT(YEAR FROM date1)*12 + EXTRACT(MONTH FROM date1)<=2018*12 + 7
AND EXTRACT(YEAR FROM date2)*12 + EXTRACT(MONTH FROM date2)>=2018*12 + 7

Total time calculation in a sql query for a day where time in 24 hour format as hhmm

I have a table with date(date), left time(varchar2(4)) and arrival time(varchar2(4)). Time taken is in 24 hour format as hhmm. If a person travel 3 times a day, what will be the query to calculate total travel time in a day?
I am using oracle 11g. Kindly help. Thank you.
Convert the value to a number and report in minutes:
select to_number(substring(time, 1, 2))*60 + to_number(substring(time, 3, 2)) as minutes
Your query would look something like:
select person, sum(to_number(substring(time, 1, 2))*60 + to_number(substring(time, 3, 2))) as minutes
from t
group by person;
I see no reason to convert this back to a string -- or to even store the value as a string instead of as a number. But if you need to, you can reverse the process to get a string.
There are 2 answers, If you want to sum time only on date then it can be done as:-
select curr_date,
sum(24 * (to_date(arrival_time, 'HH24:mi:ss')- to_date(left_time, 'HH24:mi:ss'))) as difference
from sql_prac group by curr_date,arrival_time,left_time;
The sample output is as follows:-
select curr_date,left_time,arrival_time from sql_prac;
CURR_DATE LEFT_TIME ARRIVAL_TIME
--------- -------------------- --------------------
30-JUN-17 00:00:00 15:00:00
30-JUL-17 03:30:00 11:30:00
30-AUG-17 03:00:00 12:30:00
30-SEP-17 04:00:00 17:00:00
30-JUN-17 00:00:00 15:00:00
30-JUL-17 03:30:00 11:30:00
30-AUG-17 03:00:00 12:30:00
30-SEP-17 04:00:00 17:00:00
30-SEP-17 04:00:00 17:00:00
9 rows selected
select curr_date,sum(24 * (to_date(arrival_time, 'HH24:mi:ss')- to_date(left_time, 'HH24:mi:ss'))) as difference
from sql_prac group by curr_date,arrival_time,left_time;
CURR_DATE DIFFERENCE
--------- ----------
30-JUN-17 30
30-JUL-17 16
30-SEP-17 39
30-AUG-17 19
If you want to sum it by person and date then it can be done as:-
select dept,curr_date,sum(24 * (to_date(arrival_time, 'HH24:mi:ss')- to_date(left_time, 'HH24:mi:ss'))) as difference
from sql_prac group by dept,curr_date,arrival_time,left_time order by Dept;
The sample output is as follows:-
Data in table is:-
select dept,curr_date,left_time,arrival_time from sql_prac;
DEPT CURR_DATE LEFT_TIME ARRIVAL_TIME
-------------------- --------- -------------------- --------------------
A 30-SEP-17 04:00:00 17:00:00
B 30-SEP-17 04:00:00 17:00:00
C 30-AUG-17 03:00:00 12:30:00
D 30-DEC-17 04:00:00 17:00:00
A 30-SEP-17 04:00:00 17:00:00
B 30-JUL-17 03:30:00 11:30:00
C 30-AUG-17 03:00:00 12:30:00
D 30-SEP-17 04:00:00 17:00:00
R 30-SEP-17 04:00:00 17:00:00
Data fetched using the query
select dept,curr_date,sum(24 * (to_date(arrival_time, 'HH24:mi:ss')- to_date(left_time, 'HH24:mi:ss'))) as difference
from sql_prac group by dept,curr_date,arrival_time,left_time order by Dept;
DEPT CURR_DATE DIFFERENCE
-------------------- --------- ----------
A 30-SEP-17 26
B 30-JUL-17 8
B 30-SEP-17 13
C 30-AUG-17 19
D 30-SEP-17 13
D 30-DEC-17 13
R 30-SEP-17 13