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.
Related
1st time posting here, so sorry if I messed something up.
I'm trying to figure out how many units pre day are being used across multiple products given a date range.
So if I had a table like this:
Product_id
Start_date
End_date
Units
1
07/07/2021
07/09/2021
2
2
07/08/2021
07/10/2021
4
3
07/12/2021
07/12/2021
7
The output should be something like:
Date
Units
07/07/2021
2
07/08/2021
6
07/09/2021
6
07/10/2021
4
07/11/2021
0
07/12/2021
7
Here's one option; read comments within code.
SQL> with
2 calendar as
3 -- all dates between the first START_DATE and the last END_DATE.
4 -- You need it for outer join with data you have.
5 (select mindat + level - 1 as datum
6 from (select min(start_date) mindat,
7 max(end_date) maxdat
8 from test
9 )
10 connect by level <= maxdat - mindat + 1
11 )
12 -- final query
13 select c.datum,
14 nvl(sum(t.units), 0) units
15 from calendar c left join test t on c.datum between t.start_date and t.end_date
16 group by c.datum
17 order by c.datum;
DATUM UNITS
---------- ----------
07/07/2021 2
07/08/2021 6
07/09/2021 6
07/10/2021 4
07/11/2021 0
07/12/2021 7
6 rows selected.
SQL>
I am trying to replace DB2 with Oracle DB.
In DB2, there is a WEEK function, which returns the number of weeks of the year.
For example:
SELECT week('2021-01-04') FROM sysibm.sysdummy1
Then I get the return of 2 (as DB2 WEEK function regards Sunday as the first day of the week.)
However, in Oracle, if I make a similar query, then I get a different value.
SELECT to_char(to_date('2021-01-04', 'YYYY-MM-DD'), 'WW') FROM dual;
I get the value of 1 (not 2 as Oracle regards January 1st as the first day of the week.)
Is there any other turnaround or different function to replace DB2 WEEK function?
Oracle offers two Week of Year Number functions. As you have discovered, to_char(dt, 'WW') gives a number in which the week starts on 1st of January and increments every seven days. There is also to_char(dt, 'IW') giving the ISO week number, which runs Monday to Sunday; in this case the 1st of January is Week 53 and 2021-01-04 is the first day of week 1 of 2021.
Demo on db<>fiddle
There is no function in Oracle which increments the week number on the basis of the day of the week number. You could write your own PL/SQL function to do this.
Incidentally, the first day of the week in Oracle is determined by our NLS parameters. If we run with (say) American settings Sunday is day 1; if we run with British settings then Monday is day 1.
If you want to count the number of weeks where the first day of the week is Sunday then:
SELECT FLOOR(
(DATE '2021-01-04' - NEXT_DAY( TRUNC( DATE '2021-01-04', 'YY' ) - INTERVAL '7' DAY, 'SUNDAY'))
/ 7
) + 1
AS week
FROM your_input;
Which outputs 2.
If you run it with multiple input days:
WITH your_input ( value ) AS (
SELECT DATE '2021-01-01' + LEVEL - 1
FROM DUAL
CONNECT BY LEVEL <= 32
)
SELECT value,
FLOOR(
(value - NEXT_DAY( TRUNC( value, 'YY' ) - INTERVAL '7' DAY, 'SUNDAY'))
/ 7
) + 1
AS week
FROM your_input;
Then you get the output (with the NLS_DATE_FORMAT as YYYY-MM-DD (DY)):
VALUE
WEEK
2021-01-01 (FRI)
1
2021-01-02 (SAT)
1
2021-01-03 (SUN)
2
2021-01-04 (MON)
2
2021-01-05 (TUE)
2
2021-01-06 (WED)
2
2021-01-07 (THU)
2
2021-01-08 (FRI)
2
2021-01-09 (SAT)
2
2021-01-10 (SUN)
3
2021-01-11 (MON)
3
2021-01-12 (TUE)
3
2021-01-13 (WED)
3
2021-01-14 (THU)
3
2021-01-15 (FRI)
3
2021-01-16 (SAT)
3
2021-01-17 (SUN)
4
2021-01-18 (MON)
4
2021-01-19 (TUE)
4
2021-01-20 (WED)
4
2021-01-21 (THU)
4
2021-01-22 (FRI)
4
2021-01-23 (SAT)
4
2021-01-24 (SUN)
5
2021-01-25 (MON)
5
2021-01-26 (TUE)
5
2021-01-27 (WED)
5
2021-01-28 (THU)
5
2021-01-29 (FRI)
5
2021-01-30 (SAT)
5
2021-01-31 (SUN)
6
2021-02-01 (MON)
6
db<>fiddle here
When multiple records are updated through the same form for a weekly schedule, the number of scheduled days and times can change. How to handle this?
schedules Table
id, location_id, service_id, user_id, start_date, end_date, (few more)
1 3 2 6 2020-06-23 2020-08-23
schedule_day_times Table (Before Update)
id, schedule_id(fk), day_name(between 1 to 7), start_time, end_time
1 1 2 08:00 am 10:00 am
2 1 2 11:00 am 02:00 pm
3 1 3 08:00 am 11:00 am
4 1 4 09:00 am 11:00 am
5 1 4 12:30 pm 2:00 pm
6 1 4 02:30 pm 4:00 pm
Relationship - schedules table has many schedule_day_times
After Update
id, schedule_id(fk), day_name(between 1 to 7), start_time, end_time
1 1 1 09:00 am 11:00 am
2 1 2 11:00 am 02:00 pm
3 1 4 08:00 am 11:00 am
4 1 4 12:00 pm 02:00 pm
5 1 5 09:30 am 11:00 am
6 1 5 02:30 pm 4:00 pm
7 1 5 05:30 pm 7:00 pm
Updates result in changed day_name, start_time, and end_time as in the above example.
Other Information - Form submit is same for both the tables.
What should be the best approach in this situation?
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
I need to do my reporting on week on week basis but my week number should start from 1st day of month
here is my sample data:
report_date Vol
01 nov 2014 23
03 nov 2014 34
16 nov 2014 56
30 nov 2014 44
Desired output
Week no Vol
1 57
2 56
3 0
4 44
hope its clear
Thanks
Since your desired output include "zero" rows as well, and assuming you'd like this report to work across multiple months as well:
WITH sample_data AS
(SELECT DATE '2014-11-01' AS report_date, 23 AS vol FROM DUAL
UNION ALL SELECT DATE '2014-11-03', 34 FROM DUAL
UNION ALL SELECT DATE '2014-11-16', 56 FROM DUAL
UNION ALL SELECT DATE '2014-11-30', 44 FROM DUAL)
,weeks AS
(SELECT report_month
,TO_CHAR(ROWNUM) AS week_no
FROM (SELECT DISTINCT
TRUNC(report_date,'MM') AS report_month
FROM sample_data)
CONNECT BY LEVEL <= TO_NUMBER(TO_CHAR(LAST_DAY(report_month),'W')))
SELECT TO_CHAR(weeks.report_month,'Month') AS "Month"
,weeks.week_no AS "Week no"
,NVL(sum(sample_data.vol),0) AS "Vol"
FROM weeks
LEFT JOIN sample_data
ON weeks.report_month = TRUNC(report_date,'MM')
AND weeks.week_no = to_char(report_date,'W')
GROUP BY weeks.report_month, weeks.week_no ORDER BY 1,2;
We determine the number of weeks in each month of the source data by using the LAST_DAY function, and we do a hierarchical query (CONNECT BY LEVEL <= n) to generate one row for each week in each month.
The expected output should be:
Month Week no Vol
======== ======= ===
November 1 57
November 2 0
November 3 56
November 4 0
November 5 44
select to_char(report_date, 'W'), sum(vol)
from your_table
group by to_char(report_date, 'W');
W Week of month (1-5) where week 1 starts on the first day of the
month and ends on the seventh.