我正在嘗試根據表格獲取時間間隔。
我的源表是這樣的:
| ID | OTHER_DATA | TIME_BEG | TIME_END | 期間 |
|---|---|---|---|---|
| 1 | A B C D | 10:00 | 11:00 | 15 |
| 2 | xyzt | 16:00 | 17:00 | 30 |
期望的輸出:
| ID | OTHER_DATA | ITVL_BEG | ITVL_END |
|---|---|---|---|
| 1 | A B C D | 10:00 | 10:15 |
| 1 | A B C D | 10:15 | 10:30 |
| 1 | A B C D | 10:30 | 10:45 |
| 1 | A B C D | 10:45 | 11:00 |
| 2 | xyzt | 16:00 | 16:30 |
| 2 | xyzt | 16:30 | 17:00 |
TIME_BEG和TIME_END是VARCHAR列,但我也有它們,DAY TO SECOND INTERVAL此處未顯示(分別為 TIME_BEG_INT 和 TIME_END_INT)。
基本上,我需要TRUNC (EXTRACT (DAY FROM 24 * 60 * (TIME_END_INT - TIME_BEG_INT)) / DURATION)在一個 SQL 中復制每一行時間并將 this*DURATION 添加到我的日期中。
任何幫助表示贊賞。
uj5u.com熱心網友回復:
如果您使用間隔:
CREATE TABLE table_name (ID, OTHER_DATA, TIME_BEG, TIME_END, DURATION) AS
SELECT 1, 'abcd', INTERVAL '10:00' HOUR TO MINUTE, INTERVAL '11:00' HOUR TO MINUTE, INTERVAL '15' MINUTE FROM DUAL UNION ALL
SELECT 2, 'xyzt', INTERVAL '16:00' HOUR TO MINUTE, INTERVAL '17:00' HOUR TO MINUTE, INTERVAL '30' MINUTE FROM DUAL;
然后你可以使用:
WITH range (ID, OTHER_DATA, TIME_BEG, TIME_INT_END, TIME_END, DURATION) AS (
SELECT ID,
OTHER_DATA,
TIME_BEG,
LEAST(time_beg duration, time_end),
TIME_END,
DURATION
FROM table_name
UNION ALL
SELECT ID,
OTHER_DATA,
TIME_INT_END,
LEAST(time_int_end duration, time_end),
TIME_END,
DURATION
FROM range
WHERE time_int_end < time_end
)
SEARCH DEPTH FIRST BY id SET id_order
SELECT ID,
OTHER_DATA,
TIME_BEG AS itvl_beg,
TIME_INT_END AS itvl_end
FROM range;
哪些輸出:
ID OTHER_DATA ITVL_BEG ITVL_END 1 A B C D 000000000 10:00:00.000000000 000000000 10:15:00.000000000 1 A B C D 000000000 10:15:00.000000000 000000000 10:30:00.000000000 1 A B C D 000000000 10:30:00.000000000 000000000 10:45:00.000000000 1 A B C D 000000000 10:45:00.000000000 000000000 11:00:00.000000000 2 xyzt 000000000 16:00:00.000000000 000000000 16:30:00.000000000 2 xyzt 000000000 16:30:00.000000000 000000000 17:00:00.000000000
如果您將值作為字串,則可以先將它們轉換為間隔:
CREATE TABLE table_name (ID, OTHER_DATA, TIME_BEG, TIME_END, DURATION) AS
SELECT 1, 'abcd', '10:00', '11:00', 15 FROM DUAL UNION ALL
SELECT 2, 'xyzt', '16:00', '17:00', 30 FROM DUAL;
WITH data(ID, OTHER_DATA, TIME_BEG, TIME_END, DURATION) AS (
SELECT ID,
OTHER_DATA,
TO_DSINTERVAL('0 '||TIME_BEG||':00'),
TO_DSINTERVAL('0 '||TIME_END||':00'),
NUMTODSINTERVAL(DURATION, 'MINUTE')
FROM table_name
),
range (ID, OTHER_DATA, TIME_BEG, TIME_INT_END, TIME_END, DURATION) AS (
SELECT ID,
OTHER_DATA,
TIME_BEG,
LEAST(time_beg duration, time_end),
TIME_END,
DURATION
FROM data
UNION ALL
SELECT ID,
OTHER_DATA,
TIME_INT_END,
LEAST(time_int_end duration, time_end),
TIME_END,
DURATION
FROM range
WHERE time_int_end < time_end
)
SEARCH DEPTH FIRST BY id SET id_order
SELECT ID,
OTHER_DATA,
TIME_BEG AS itvl_beg,
TIME_INT_END AS itvl_end
FROM range;
db<>在這里擺弄
uj5u.com熱心網友回復:
這是基于間隔前計算的經典解決方案 DATE
with time_int(ID, OTHER_DATA, ITVL_BEG, ITVL_END, DURATION, TIME_END) as (
select
ID, OTHER_DATA, TIME_BEG,
to_char(to_date(time_beg,'HH24:mi') duration/(24*60),'HH24:mi'),
DURATION, TIME_END
from tab
union all
select
ID, OTHER_DATA, ITVL_END,
to_char(to_date(ITVL_END,'HH24:mi') duration/(24*60),'HH24:mi'),
DURATION, TIME_END
from time_int
where ITVL_END <= TIME_END
)
select
ID, OTHER_DATA, ITVL_BEG, ITVL_END
from time_int
order by 1,3;
ID OTHE ITVL_ ITVL_
---------- ---- ----- -----
1 abcd 10:00 10:15
1 abcd 10:15 10:30
1 abcd 10:30 10:45
1 abcd 10:45 11:00
1 abcd 11:00 11:15
2 xyzt 16:00 16:30
2 xyzt 16:30 17:00
2 xyzt 17:00 17:30
甲遞回CTE用于與步驟基于以下計算獲得下一個間隔邊界(假設你的時間被存盤為VARCHAR2)
to_char(to_date(time_beg,'HH24:mi') duration/(24*60),'HH24:mi')
請注意,您可以轉換10:00為日期,并且 Oracle 提供了您不需要的默認缺失日、月和年,因為在增加之后duration您會轉換回HH24:MI字串。
轉載請註明出處,本文鏈接:https://www.uj5u.com/ruanti/314338.html
上一篇:獲取繁忙時間重疊的可用日期間隔
