I have one requirement where I have to show the records between specific date and time every day of one week - oracle

I have one requirement where I have to show the records between specific date and time every day in one week duration.
in one week duration( 2019-04-01 till 2019-04-06) ,for instance record of 2019-04-01 at 19 PM till 8 Am of 2019-04-02 ,and record of 2019-04-02 at 19 PM till 08 AM of 2019-04-03 and ...
would you please help me!

Use recursive query to create proper periods then join with your data or do it simpler with condition like here:
select callbegin, callerno
from table4
where callerno in ('7032','750')
and callbegin between timestamp '2019-04-01 19:00:00'
and timestamp '2019-04-06 08:00:00'
and ('19' <= to_char(callbegin, 'hh24') or to_char(callbegin, 'hh24') < '08');
demo

Here's how I understood the question.
SQL> alter session set nls_date_format = 'dd.mm.yyyy hh24:mi';
Session altered.
SQL> break on period;
SQL> with
2 data (id, datum) as
3 (select 1, to_date('01.04.2019 15:30', 'dd.mm.yyyy hh24:mi') from dual union all
4 select 2, to_date('01.04.2019 20:00', 'dd.mm.yyyy hh24:mi') from dual union all -- 1st
5 select 3, to_date('02.04.2019 01:15', 'dd.mm.yyyy hh24:mi') from dual union all -- 1st perios
6 select 4, to_date('02.04.2019 11:00', 'dd.mm.yyyy hh24:mi') from dual union all
7 select 5, to_date('02.04.2019 23:15', 'dd.mm.yyyy hh24:mi') from dual union all -- 2nd period
8 select 6, to_date('03.04.2019 00:10', 'dd.mm.yyyy hh24:mi') from dual union all -- 2nd
9 select 7, to_date('04.04.2019 22:20', 'dd.mm.yyyy hh24:mi') from dual -- 3rd period
10 ),
11 test as
12 (select date '2019-04-01' dstart,
13 date '2019-04-06' dend
14 from dual
15 ),
16 inter as
17 (select dstart + level - 1 datum
18 from test
19 connect by level <= dend - dstart + 1
20 ),
21 from_to as
22 (select datum + 19/24 date_from,
23 lead(datum) over (order by datum) + 8/24 date_to
24 from inter
25 )
26 select f.date_From ||' - '|| f.date_to period,
27 d.id,
28 d.datum
29 from data d join from_to f on 1 = 1
30 where d.datum between f.date_from and f.date_to
31 order by f.date_From, d.id;
PERIOD ID DATUM
----------------------------------- ---------- ----------------
01.04.2019 19:00 - 02.04.2019 08:00 2 01.04.2019 20:00
3 02.04.2019 01:15
02.04.2019 19:00 - 03.04.2019 08:00 5 02.04.2019 23:15
6 03.04.2019 00:10
04.04.2019 19:00 - 05.04.2019 08:00 7 04.04.2019 22:20
SQL>

This is how to filter data by days and time by one week:
With date_list as (
Select
to_date(to_char( (sysdate - level), 'yyyymmdd') || '19', 'yyyymmddhh24') begin_time,
to_date(to_char( ((sysdate - level)+1), 'yyyymmdd') || '08', 'yyyymmddhh24') end_time
From dual connect by level <= 7
)
Select begin_time, your_table.*
From
your_table t1,
date_list t2
Where
t1.your_date between t2.begin_time and t2.end_time;

Related

Oracle: Return the specific records based on one column date

I have a database structure as below.
period
month
start_date
1
April
2022-04-01
2
May
2022-05-07
3
June
2022-06-04
4
July
2022-07-02
5
August
2022-08-06
6
September
2022-09-03
7
October
2022-10-01
8
November
2022-11-05
9
December
2022-12-03
10
January
2023-01-01
11
February
2023-02-04
12
March
2023-03-04
End date of the year is 2023-03-31.
Based on current_date, how do I select the query to return where the current date falls under Period 6.
My current query as below.
SELECT period FROM table1 as a
WHERE
a.start_date = (SELECT MAX(start_date) FROM table1 as b WHERE
b.start_date <=current_date) and ROWNUM <= 1
Is there anyway to improve the current query which to avoid using subquery?
Today is September 22nd, so - would this do?
Some sample data:
SQL> with test (period, month, start_date) as
2 (select 1, 'april' , date '2022-04-01' from dual union all
3 select 5, 'august' , date '2022-08-06' from dual union all
4 select 6, 'september', date '2022-09-03' from dual union all
5 select 7, 'october' , date '2022-10-01' from dual union all
6 select 10, 'january' , date '2023-01-01' from dual union all
7 select 12, 'march' , date '2023-03-04' from dual
8 ),
Query begins here:
9 temp as
10 (select period, month, start_date,
11 row_number() over (order by start_date desc) rn
12 from test
13 where start_date <= sysdate
14 )
15 select period
16 from temp
17 where rn = 1
18 /
PERIOD
----------
6
SQL>
It still uses a subquery (or a CTE, as in my example), but - as opposed to your approach, it selects from the source table only once, so performance should be improved.
A few more tests: instead of sysdate (line #13), presume that today is September 2nd (which means that it is in period #5):
9 temp as
10 (select period, month, start_date,
11 row_number() over (order by start_date desc) rn
12 from test
13 where start_date <= date '2022-09-02'
14 )
15 select period
16 from temp
17 where rn = 1;
PERIOD
----------
5
SQL>
Or, if today were August 7th:
9 temp as
10 (select period, month, start_date,
11 row_number() over (order by start_date desc) rn
12 from test
13 where start_date <= date '2022-08-07'
14 )
15 select period
16 from temp
17 where rn = 1;
PERIOD
----------
5
SQL>
Your rule for the start_date appears to be:
If the month is January (first month of the calendar year) or April (typically, first month of the financial year) then use the 1st of that month;
Otherwise use the 1st Saturday of the month.
If that is the case then you can calculate the start date of the next month and use the query:
SELECT *
FROM table1
WHERE start_date <= SYSDATE
AND SYSDATE < CASE
WHEN EXTRACT(MONTH FROM ADD_MONTHS(start_date, 1))
IN (1, 4) -- 1st month of calendar or financial year
THEN TRUNC(ADD_MONTHS(start_date, 1), 'MM')
ELSE NEXT_DAY(TRUNC(ADD_MONTHS(start_date, 1), 'MM') - 1, 'SATURDAY')
END
Then, for your sample data:
CREATE TABLE table1 (
period NUMBER(2,0),
month VARCHAR2(9)
GENERATED ALWAYS AS (
CAST(
TO_CHAR(start_date, 'FXMonth', 'NLS_DATE_LANGUAGE=English')
AS VARCHAR2(9)
)
),
start_date DATE
);
INSERT INTO table1 (period, start_date)
SELECT LEVEL,
CASE
WHEN EXTRACT(MONTH FROM ADD_MONTHS(DATE '2022-04-01', LEVEL - 1))
IN (1, 4) -- 1st month of calendar or financial year
THEN ADD_MONTHS(DATE '2022-04-01', LEVEL - 1)
ELSE NEXT_DAY(ADD_MONTHS(DATE '2022-04-01', LEVEL - 1) - 1, 'SATURDAY')
END
FROM DUAL
CONNECT BY LEVEL <= 12;
Outputs:
PERIOD
MONTH
START_DATE
6
September
2022-09-03 00:00:00
fiddle

Timestamp to_char subquery

I have the following query but I need a particular format (HH24,MI,SS) for the results that I get in column "elapsed". Can I do that with a subquery?
SELECT
trunc(dstamp) "DATE",
to_char(dstamp, 'HH24:MI:SS') "Time"
, user_id
, dstamp - lag(dstamp) OVER (
PARTITION BY user_id ORDER BY dstamp
) AS elapsed
, COUNT(CODE) "Lines_Picked"
, ROUND(sum(update_qty / cast(substr(sku_id, instr(sku_id, '-', 1, 1) + 1
, instr(sku_id, '-', 1, 2) - 1 - instr(sku_id, '-', 1, 1)) as integer))) "CASES_PICKED"
FROM v_inventory_transaction
WHERE client_id = 'USKIDS2CA'
AND code = 'Pick'
AND list_id IS NOT NULL
AND STATION_ID LIKE 'R%'
AND reference_id NOT LIKE '%-FK%'
AND trunc(dstamp) = to_date('03/23/2022','mm/dd/yyyy')
GROUP BY
user_id,
dstamp
, cast(substr(sku_id, instr(sku_id, '-', 1, 1) + 1
, instr(sku_id, '-', 1, 2) - 1 - instr(sku_id, '-', 1, 1)) as integer)
What is "timestamp" from the title? Which datatype is it? DATE or TIMESTAMP?
If it is TIMESTAMP, extract helps a lot:
SQL> with temp (user_id, dstamp) as
2 (select 1, to_timestamp('27.03.2022 08:08', 'dd.mm.yyyy hh24:mi') from dual union all
3 select 1, to_timestamp('27.03.2022 05:30', 'dd.mm.yyyy hh24:mi') from dual union all
4 select 1, to_timestamp('27.03.2022 02:28', 'dd.mm.yyyy hh24:mi') from dual
5 )
6 select user_id,
7 dstamp,
8 --
9 to_char(extract (hour from dstamp - lag(dstamp) over (partition by user_id order by dstamp)), 'FM00') ||':'||
10 to_char(extract (minute from dstamp - lag(dstamp) over (partition by user_id order by dstamp)), 'FM00') ||':'||
11 to_char(extract (second from dstamp - lag(dstamp) over (partition by user_id order by dstamp)), 'FM00') result
12 from temp
13 order by user_id, dstamp;
USER_ID DSTAMP RESULT
---------- ----------------------------------- -----------
1 27-MAR-22 02.28.00.000000000 AM ::
1 27-MAR-22 05.30.00.000000000 AM 03:02:00
1 27-MAR-22 08.08.00.000000000 AM 02:38:00
SQL>
If it is DATE, then ELAPSED currently represents number of days between dstamp and its previous row's value per user_id. As it seems that that number is always less than 1 day (as you want result in hh24:mi:ss format), a simple option is to apply combination of
to_char(to_date(elapsed, 'sssss'), 'hh24:mi:ss')
and get the result. Step-by-step (so that you'd see which result you get for each step):
SQL> with temp (user_id, dstamp) as
2 (select 1, to_date('27.03.2022 08:08', 'dd.mm.yyyy hh24:mi') from dual union all
3 select 1, to_date('27.03.2022 05:30', 'dd.mm.yyyy hh24:mi') from dual union all
4 select 1, to_date('27.03.2022 02:28', 'dd.mm.yyyy hh24:mi') from dual
5 )
6 select user_id,
7 dstamp,
8 --
9 dstamp - lag(dstamp) over (partition by user_id order by dstamp) as elapsed_days,
10 --
11 round((dstamp - lag(dstamp) over (partition by user_id order by dstamp)) *
12 24 * 60 * 60) elapsed_seconds,
13 --
14 to_char(to_date(round((dstamp - lag(dstamp) over (partition by user_id
15 order by dstamp)) *
16 24 * 60 * 60), 'sssss'),
17 'hh24:mi:ss') result
18 from temp
19 order by user_id, dstamp;
USER_ID DSTAMP ELAPSED_DAYS ELAPSED_SECONDS RESULT
---------- ------------------- ------------ --------------- --------
1 27.03.2022 02:28:00
1 27.03.2022 05:30:00 .126388889 10920 03:02:00
1 27.03.2022 08:08:00 .109722222 9480 02:38:00
SQL>
However, if elapsed can be larger than 1 day so that it exceeds number of seconds in a day (that's 24 * 60 * 60 = 86400), that won't work so you'll have to actually calculate the result. However, query then becomes really ugly so you'd rather use another CTE (or a subquery) to first extract elapsed and work with it, instead of using dstamp - lag(...) all the time.
Therefore, I hope it is the timestamp after all.

Oracle - How to know the load volume by times of a table?

I have some tables in Oracle and I would like to know the variations of the table by sections of time.
I explain, I need a query/script to know how often data is loaded / updated in the table.
example
Can anyone give me ideas on how to do something like that or similar?
Thanks!
Split a day to hours (CTEs times and periods) and apply aggregates to values stored in your_table (which is joined to "fabricated" hours). For example:
SQL> with times as
2 (select trunc(sysdate) + (level - 1)/24 val
3 from dual
4 connect by level <= 25
5 ),
6 periods as
7 (select val val_from,
8 lead(val) over (order by val) val_to
9 from times
10 ),
11 your_table (date_column, ins, upd) as
12 (select trunc(sysdate) + 13/24 + 25/(24*60), 100, 18 from dual union all
13 select trunc(sysdate) + 13/24 + 25/(24*60), 225, null from dual union all
14 select trunc(sysdate) + 14/24 + 33/(24*60), 203, 112 from dual union all
15 select trunc(sysdate) + 15/24 + 15/(24*60), null, 687 from dual union all
16 select trunc(sysdate) + 15/24 + 18/(24*60), null, 987 from dual
17 )
18 select to_char(p.val_from, 'hh24:mi') ||' - '||
19 to_char(p.val_to , 'hh24:mi') period,
20 count(ins) cnt_insert,
21 count(upd) cnt_update
22 from periods p join your_table t on t.date_column >= p.val_from
23 and t.date_column < p.val_to
24 where p.val_to is not null
25 group by p.val_from, p.val_to
26 order by p.val_From;
PERIOD CNT_INSERT CNT_UPDATE
------------- ---------- ----------
13:00 - 14:00 2 1
14:00 - 15:00 1 1
15:00 - 16:00 0 2
SQL>

Oracle time table - Fill in missing times

I have a query that gives me renders per minute (when there is a render during the minute)
select count(*) as "Total Rendered", to_char(r.request_dt, 'YYYY-MM-DD HH24:MI') as "ByMinute" from form_render r where r.form_type_id = 49
and r.request_dt >= to_timestamp('09-16-2015 08:00', 'mm-dd-yyyy hh24:mi')
group by to_char(r.request_dt, 'YYYY-MM-DD HH24:MI')
order by to_char(r.request_dt, 'YYYY-MM-DD HH24:MI') desc
Total Rendered | ByMinute
19 2015-09-17 09:31
10 2015-09-17 09:30
1 2015-09-17 09:28
6 2015-09-17 09:27
18 2015-09-17 09:25
22 2015-09-17 09:24
12 2015-09-17 09:23
13 2015-09-17 09:21
22 2015-09-17 09:20
However I want a row for all times (by minute) even when there were none rendered (add rows for times when no renders occurred...09:22,09:26, 09:29)
So something like this
Total Rendered | ByMinute
19 2015-09-17 09:31
10 2015-09-17 09:30
0 2015-09-17 09:29
1 2015-09-17 09:28
6 2015-09-17 09:27
0 2015-09-17 09:26
18 2015-09-17 09:25
22 2015-09-17 09:24
12 2015-09-17 09:23
0 2015-09-17 09:22
13 2015-09-17 09:21
22 2015-09-17 09:20
Any help is greatly appreciated
Sean
===========================================================================
Sept 20 attempt.....
===========================================================================
Thank you very much for taking the time to put this together. SQL is definitely not my strength as I am sure you can tell!
So I have patched together the time table and my query but am getting an error (ORA01843: not a valid month.)
When I run my query by itself
select count(*)as "Total_Rendered" , to_char(r.request_dt, 'MM/DD/YYYY HH24:MI')as "ByMinute" from form_render r where r.form_type_id = 49
and r.request_dt >= to_timestamp('09/17/2015 09:11', 'mm/dd/yyyy hh24:mi') and r.request_dt <= to_timestamp('09/17/2015 09:18', 'mm/dd/yyyy hh24:mi')
group by to_char(r.request_dt, 'MM/DD/YYYY HH24:MI')
order by 2 desc
I get the following
TOTAL_RENDERED | ByMinute
---------------------------
4 | 09/17/2015 09:18
16 | 09/17/2015 09:17
4 | 09/17/2015 09:16
2 | 09/17/2015 09:11
When I run the minute_table query
WITH min_date AS /* replace start and stop timestamp here */
(SELECT to_date('09/17/2015 09:11', 'MM/DD/YYYY hh24:mi') minute FROM dual
),
max_date AS
(SELECT to_date('09/17/2015 09:18', 'MM/DD/YYYY hh24:mi') minute FROM dual
),
minute_table AS
(SELECT
(SELECT minute FROM min_date
) + (rownum -1)/(24*60) AS by_minute
FROM dual
CONNECT BY level <=
(SELECT (24*60) *(
(SELECT minute FROM max_date
) -
(SELECT minute FROM min_date
))+1
FROM dual
)
)
select * from minute_table
I get the following....
9/17/2015 9:11:00 AM
9/17/2015 9:12:00 AM
9/17/2015 9:13:00 AM
9/17/2015 9:14:00 AM
9/17/2015 9:15:00 AM
9/17/2015 9:16:00 AM
9/17/2015 9:17:00 AM
9/17/2015 9:18:00 AM
so far so good.
When I combine the two queries to get this query
WITH min_date AS /* replace start and stop timestamp here */
(SELECT to_date('09/17/2015 09:11', 'MM/DD/YYYY hh24:mi:ss') minute FROM dual
),
max_date AS
(SELECT to_date('09/17/2015 09:18', 'MM/DD/YYYY hh24:mi:ss') minute FROM dual
),
minute_table AS
(SELECT
(SELECT minute FROM min_date
) + (rownum -1)/(24*60) AS by_minute
FROM dual
CONNECT BY level <=
(SELECT (24*60) *(
(SELECT minute FROM max_date
) -
(SELECT minute FROM min_date
))+1
FROM dual
)
),
tbl AS
(
select count(*)as "Total_Rendered" , to_char(r.request_dt, 'MM/DD/YYYY HH24:MI')as "ByMinute" from form_render r where r.form_type_id = 49
and r.request_dt >= to_timestamp('09/17/2015 09:11', 'mm/dd/yyyy hh24:mi') and r.request_dt <= to_timestamp('09/17/2015 09:18', 'mm/dd/yyyy hh24:mi')
group by to_char(r.request_dt, 'MM/DD/YYYY HH24:MI')
order by 2 desc
)
SELECT minute_table.by_minute ,
NVL(tbl."Total_Rendered",'0') AS total_rendered
FROM minute_table
left OUTER JOIN tbl
ON tbl."ByMinute" = minute_table.by_minute
order by 1 desc
;
I get an error ORA01843: not a valid month.
I am not entirely certain why the error is occuring but I am confident it has to do with the format differences between the columns I am joining on?
The format of the dates in the time table vs my table are likely the cause but I am not certain.
Time Table has 9/17/2015 9:11:00 AM and
my query has 09/17/2015 09:11 (notice missing leading zero on Month, seconds and AM)
Any help is appreciated.
Thanks again for your time and expertise....
Sean
Slightly different solution without dependency on 12c and with "parameters" for start and stop minutes.
WITH min_date AS /* replace start and stop timestamp here */
(SELECT to_date('2015-09-17 09:28','yyyy-mm-dd hh24:mi') minute FROM dual
),
max_date AS
(SELECT to_date('2015-09-17 09:31','yyyy-mm-dd hh24:mi') minute FROM dual
),
minute_table AS
(SELECT
(SELECT minute FROM min_date
) + (rownum -1)/(24*60) AS by_minute
FROM dual
CONNECT BY level <=
(SELECT (24*60) *(
(SELECT minute FROM max_date
) -
(SELECT minute FROM min_date
))+1
FROM dual
)
),
tbl AS
(SELECT 19 Total_Rendered,
to_date('2015-09-17 09:31','YYYY-MM-DD HH24:MI') By_Minute
FROM dual
UNION ALL
SELECT 1,to_date('2015-09-17 09:30','YYYY-MM-DD HH24:MI') FROM dual
UNION ALL
SELECT 19,to_date('2015-09-17 09:28','YYYY-MM-DD HH24:MI') FROM dual
)
SELECT minute_table.by_minute ,
NVL(tbl.total_rendered,'0') AS total_rendered
FROM minute_table
LEFT OUTER JOIN tbl
ON tbl.By_Minute = minute_table.by_minute
;
So this is working in Oracle 12c. But you have to change it for your use.
with tbl(Total_Rendered, ByMinute) as (
select 19,to_date('2015-09-17 09:31','YYYY-MM-DD HH24:MI') from dual union all
select 1,to_date('2015-09-17 09:30','YYYY-MM-DD HH24:MI') from dual union all
select 19,to_date('2015-09-17 09:28','YYYY-MM-DD HH24:MI') from dual )
select nvl(tbl.total_rendered,'0') as total_rendered,by_minute from
(select to_date('2015-09-17 09:28','YYYY-MM-DD HH24:MI') + (1/24/60) * column_value as by_minute from
TABLE( CAST( MULTISET( SELECT LEVEL FROM DUAL
CONNECT BY LEVEL <= 3 ) AS SYS.ODCINUMBERLIST
) )) time_range
left outer join
tbl
on tbl.ByMinute = time_range.by_minute
Output
TOTAL_RENDERED BY_MINUTE
0 17-SEP-2015 09:29:00
1 17-SEP-2015 09:30:00
19 17-SEP-2015 09:31:00
What I did is first I am using a temporary table tbl which will have data as your input. Then I generated timestamp from '17-SEP-2015 09:29:00' - '17-SEP-2015 09:31:00'to generate a time_range
Now I did a left outer join from this time_range to tbl which has missing data. For the rows not in tbl, I am printing 0.
You can use this query and edit it to get the time_range and join with your data to get this output.

Get Gap between time range

In WORK_TIME column in my database table (EMP_WORKS), i have records as below.
WORK_TIME
19:03:00
20:00:00
21:02:00
21:54:00
23:04:00
00:02:00
i want to create a database view using these data. for it i need to get Gap between these times as below.
WORK_TIME GAP
19:03:00 -
20:00:00 00:57:00 (Gap between 19:03:00 and 20:00:00)
21:02:00 01:02:00 (Gap between 20:00:00 and 21:02:00)
21:54:00 00:52:00 (Gap between 21:02:00 and 21:54:00)
23:04:00 01:10:00 (Gap between 21:54:00 and 23:04:00)
00:02:00 00:58:00 (Gap between 23:04:00 and 00:02:00)
How could i do this ?
This query will get you the differences in hours:
SELECT
work_time,
( work_time - LAG(work_time) OVER (ORDER BY work_time) ) * 24 AS gap
FROM emp_works
Example on SQL Fiddle returns this:
WORK_TIME GAP
November, 07 2012 19:03:00+0000 (null)
November, 07 2012 20:00:00+0000 0.95
November, 07 2012 21:02:00+0000 1.033333333333
November, 07 2012 21:54:00+0000 0.866666666667
November, 07 2012 23:04:00+0000 1.166666666667
November, 08 2012 00:02:00+0000 0.966666666667
First you will need to have a primary key in the table containing the DATE/TIME field.
I have set up this demo on SQL Fiddle .. Have a look
I have represented the gap as a factor of hours between the two times. You can manipulate the figure to represent minutes, or days, whatever.
SELECT
TO_CHAR(A.WORK_TIME,'HH24:MI:SS') WORK_FROM,
TO_CHAR(B.WORK_TIME,'HH24:MI:SS') WORK_TO,
ROUND(24*(B.WORK_TIME-A.WORK_TIME),2) GAP FROM
sample A,
SAMPLE B
WHERE A.ID+1 = B.ID(+)
If your primary key values have difference greater than 1 (gaps within the values of the primary key) then you will need to offset the value dynamically like this:
SELECT
TO_CHAR(A.WORK_TIME,'HH24:MI:SS') WORK_FROM,
TO_CHAR(B.WORK_TIME,'HH24:MI:SS') WORK_TO,
ROUND(24*(B.WORK_TIME-A.WORK_TIME),2) GAP FROM
sample A,
SAMPLE B
WHERE b.ID = (select min(C.ID) from sample c where c.id>A.ID)
According to your desired result, provided in the question, you want to see time interval. And also I suppose that the WORK_TIME column is of date datatype and there is a date part(otherwise there will be a negative result of subtraction (previous value of WORK_TIME from 00.02.00)).
SQL> create table Work_times(
2 work_time
3 ) as
4 (
5 select to_date('01.01.2012 19:03:00', 'dd.mm.yyyy hh24:mi:ss') from dual union all
6 select to_date('01.01.2012 20:00:00', 'dd.mm.yyyy hh24:mi:ss') from dual union all
7 select to_date('01.01.2012 21:02:00', 'dd.mm.yyyy hh24:mi:ss') from dual union all
8 select to_date('01.01.2012 21:54:00', 'dd.mm.yyyy hh24:mi:ss') from dual union all
9 select to_date('01.01.2012 23:04:00', 'dd.mm.yyyy hh24:mi:ss') from dual union all
10 select to_date('02.01.2012 00:02:00', 'dd.mm.yyyy hh24:mi:ss') from dual
11 )
12 /
Table created
SQL>
SQL> select to_char(t.work_time, 'hh24.mi.ss') work_time
2 , (t.work_time -
3 lag(t.work_time) over(order by WORK_TIME)) day(1) to second(0) Res
4 from work_times t
5 ;
WORK_TIME RES
--------- -------------------------------------------------------------------------------
19.03.00
20.00.00 +0 00:57:00
21.02.00 +0 01:02:00
21.54.00 +0 00:52:00
23.04.00 +0 01:10:00
00.02.00 +0 00:58:00
6 rows selected

Resources