如何从开始/结束日期记录中拆分多个记录中的记录

时间:2019-09-05 04:18:48

标签: oracle oracle-sqldeveloper

我正在尝试将记录从Oracle中的开始/结束日期拆分为多个记录 我有这样的数据

MachineID | start date | end date | running time | WC01 | 2019/09/05 07:00 | 2019/09/07 09:00 | 26:00 |

我想将记录从每天08:00拆分到每天08:00

MachineID | running date | running time | WC01 | 2019/09/05 | 1:00 | WC01 | 2019/09/06 | 24:00 | WC01 | 2019/09/07 | 1:00 |

谢谢您的帮助!

2 个答案:

答案 0 :(得分:1)

我们可以通过日历表中的帮助来处理此问题,该表包含您希望出现在数据集中的所有日期以及每分钟的单独记录:

WITH dates AS (
    SELECT TIMESTAMP '2019-09-05 00:00:00' + NUMTODSINTERVAL(rownum, 'MINUTE') AS dt
    FROM dual
    CONNECT BY level <= 5000
)

SELECT
    m.MachineID,
    TRUNC(d.dt) AS running_date,
    COUNT(t.MachineID) / 60 AS running_hours
FROM dates d
CROSS JOIN (SELECT DISTINCT MachineID FROM yourTable) m
LEFT JOIN yourTable t
    ON d.dt >= t.start_date AND d.dt < t.end_date
WHERE
    TO_CHAR(d.dt, 'HH24') >= '08' AND TO_CHAR(d.dt, 'HH24') < '21'
GROUP BY
    m.MachineID,
    TRUNC(d.dt)
ORDER BY
    TRUNC(d.dt);

screen capture of result set

Demo

答案 1 :(得分:1)

您可以尝试以下查询:

SELECT
    MACHINEID,
    RUNNING_DATE,
    DECODE(RUNNING_DATE, TRUNC(START_DATE), CASE
        WHEN DIFF_START < 0  THEN 0
        WHEN DIFF_START > 12 THEN 12
        ELSE DIFF_START
    END, TRUNC(END_DATE), CASE
        WHEN DIFF_END < 0  THEN 0
        WHEN DIFF_END > 12 THEN 12
        ELSE DIFF_END
    END, 24) AS RUNNING_HOURS
FROM
    (
        SELECT
            MACHINEID,
            RUNNING_DATE,
            ROUND(24 *((TRUNC(START_DATE + LVL - 1) + 8 / 24) - START_DATE)) AS DIFF_START,
            ROUND(24 *(END_DATE -(TRUNC(START_DATE + LVL - 1) + 8 / 24))) AS DIFF_END,
            START_DATE,
            END_DATE
        FROM
            (
                SELECT
                    DISTINCT MACHINEID,
                    LEVEL   AS LVL,
                    START_DATE,
                    END_DATE,
                    TRUNC(START_DATE + LEVEL - 1) AS RUNNING_DATE
                FROM
                    YOURTABLE
                CONNECT BY
                    LEVEL <= TRUNC(END_DATE) - TRUNC(START_DATE) + 1
            )
    );

db<>fiddle demo

在不满足您要求的任何地方更改逻辑。我已经创建了查询,其中考虑了示例数据和预期输出。

干杯!