oracle 如何基于日期将一行数据转换为多行数据

slwdgvem  于 2023-02-03  发布在  Oracle
关注(0)|答案(1)|浏览(336)

我希望根据start_time和end_time将数据从一行转换为多行。
输入数据:
| 识别号|开始时间|结束时间|停机_分钟|
| - ------|- ------|- ------|- ------|
| ABC123|2022年11月22日12时01分|2022年11月29日14时33分|小行星10232.47|
我需要为此需求编写SQL:
输出数据:
| 识别号|开始时间|结束时间|停机_分钟|
| - ------|- ------|- ------|- ------|
| ABC123|2022年11月22日12时01分|2022年11月23日7时|小行星1138.55|
| ABC123|2022年11月23日7时|2022年11月24日7时|小行星1440|
| ABC123|2022年11月24日7时|2022年11月25日7时|小行星1440|
| ABC123|2022年11月25日7时|2022年11月26日7时|小行星1440|
| ABC123|2022年11月26日7时|2022年11月27日7时|小行星1440|
| ABC123|2022年11月27日7时|2022年11月28日7时|小行星1440|
| ABC123|2022年11月28日7时|2022年11月29日7时|小行星1440|
| ABC123|2022年11月29日7时|2022年11月29日14时33分|四百五十三块九二|
enter image description here

e4eetjau

e4eetjau1#

您可以使用递归查询将数据拆分为从上午7点开始的每个24小时时段的行:

WITH days (id, start_time, day_end, end_time, day_mins, down_mins) AS (
  SELECT id,
         start_time,
         LEAST(TRUNC(start_time - INTERVAL '7' HOUR) + INTERVAL '31' HOUR, end_time),
         end_time,
         LEAST((LEAST(TRUNC(start_time - INTERVAL '7' HOUR) + INTERVAL '31' HOUR, end_time) - start_time) * 24 * 60, down_mins),
         down_mins - LEAST((LEAST(TRUNC(start_time - INTERVAL '7' HOUR) + INTERVAL '31' HOUR, end_time) - start_time) * 24 * 60, down_mins)
  FROM   table_name
UNION ALL
  SELECT id,
         day_end,
         LEAST(day_end + INTERVAL '24' HOUR, end_time),
         end_time,
         LEAST((LEAST(day_end + INTERVAL '24' HOUR, end_time) - day_end) * 24 * 60, down_mins),
         down_mins - LEAST((LEAST(day_end + INTERVAL '24' HOUR, end_time) - day_end) * 24 * 60, down_mins)
  FROM   days
  WHERE  day_end < end_time
  AND    down_mins > 0
)
SEARCH DEPTH FIRST BY id, start_time SET order_id
SELECT id,
       start_time,
       day_end AS end_time,
       day_mins AS down_mins
FROM   days;

其中,对于示例数据:

CREATE TABLE table_name (ID, Start_Time, End_Time, Down_Mins) AS
SELECT 'ABC123',
       DATE '2022-11-23' + INTERVAL '7' HOUR - NUMTODSINTERVAL(1138.55, 'MINUTE'),
       DATE '2022-11-23' + INTERVAL '7' HOUR + NUMTODSINTERVAL(10232.47 - 1138.55, 'MINUTE'),
       10232.47
FROM   DUAL;

输出:
| 识别号|开始时间|结束时间|下降_分钟|
| - ------|- ------|- ------|- ------|
| ABC123|2022年11月22日12时01分27秒|2022年11月23日07时00分|小行星1138.55|
| ABC123|2022年11月23日07时00分|2022年11月24日07时00分|小行星1440|
| ABC123|2022年11月24日07时00分|2022年11月25日07时00分|小行星1440|
| ABC123|2022年11月25日07时00分|2022年11月26日07时00分|小行星1440|
| ABC123|2022年11月26日07时00分|2022年11月27日07时00分|小行星1440|
| ABC123|2022年11月27日07时00分|2022年11月28日07时00分|小行星1440|
| ABC123|2022年11月28日07时00分|2022年11月29日07时00分|小行星1440|
| ABC123|2022年11月29日07时00分|2022年11月29日14时33分55秒|453.916666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666|
fiddle

相关问题