Я хочу перенести расчет из электронной таблицы Excel в запрос Oracle SQL.

Есть три предопределенных столбца: ID, IncommingDate и ProcessingTime.

Теперь я хочу вычислить два дополнительных столбца, а именно Processing Start и Processing End.

Результат должен выглядеть следующим образом:

Result Excel

С формулами:

Formula 1 Formula 2

Можно видеть, что ProcessingStart одной записи должно быть максимумом ее IncommingDate и ProcessingEnd предыдущей записи.

Как я могу добиться этого с помощью SQL?

Я подготовил пример запроса здесь:

WITH example AS
    (
        SELECT
            1                                                       AS id,
            to_date ('01.01.2018 00:00:00','dd.MM.yyyy HH24:mi:ss') AS IncommingDate,
            60                                                      AS "Processing Time [sec.]"
        FROM
            dual
        UNION ALL
        SELECT
            2,
            to_date ('01.01.2018 00:05:00','dd.MM.yyyy HH24:mi:ss'),
            60
        FROM
            dual
        UNION ALL
        SELECT
            3,
            to_date ('01.01.2018 00:05:30','dd.MM.yyyy HH24:mi:ss'),
            60
        FROM
            dual
        UNION ALL
        SELECT
            4,
            to_date ('01.01.2018 00:10:00','dd.MM.yyyy HH24:mi:ss'),
            60
        FROM
            dual
    )


SELECT
    *
FROM
    example

Кто-нибудь из вас знает, как это сделать?

1
steelcook 5 Окт 2018 в 13:14

1 ответ

Лучший ответ

Похоже, вам нужно использовать рекурсивный факторинг подзапросов:

with rcte (id, IncommingDate, ProcessingTime, ProcessingStart, ProcessingEnd) as (
  select id,
    IncommingDate,
    ProcessingTime,
    IncommingDate,
    IncommingDate + (ProcessingTime/86400)
  from example
  where id = 1
  union all
  select e.id,
    e.IncommingDate,
    e.ProcessingTime,
    greatest(e.IncommingDate, r.ProcessingEnd),
    greatest(e.IncommingDate, r.ProcessingEnd) + (e.ProcessingTime/86400)
  from rcte r
  -- assumes IDs are the ordering criteris and are contiguous
  join example e on e.id = r.id + 1
)
select * from rcte;

        ID INCOMMINGDATE       PROCESSINGTIME PROCESSINGSTART     PROCESSINGEND      
---------- ------------------- -------------- ------------------- -------------------
         1 2018-01-01 00:00:00             60 2018-01-01 00:00:00 2018-01-01 00:01:00
         2 2018-01-01 00:05:00             60 2018-01-01 00:05:00 2018-01-01 00:06:00
         3 2018-01-01 00:05:30             60 2018-01-01 00:06:00 2018-01-01 00:07:00
         4 2018-01-01 00:10:00             60 2018-01-01 00:10:00 2018-01-01 00:11:00

Элемент привязки имеет идентификатор 1 и может выполнять простые вычисления для этого первого шага, чтобы получить время начала / окончания.

Затем рекурсивный член находит следующую исходную строку и использует greatest(), чтобы решить, делать ли вычисления на основе времени поступления или предыдущего времени окончания.

Предполагается, что порядок основан на идентификаторах и что они являются смежными. Если это не то, как вы на самом деле заказываете, тогда все немного сложнее.

1
Alex Poole 5 Окт 2018 в 12:10