有条件地执行滞后的 MAX 和 MIN 计算 - Oracle SQL

Conditionally perform a lagging MAX and MIN calculation - Oracle SQL

我有一个 table 的数据是这样的:

|   Order   | Step | StepStart |  StepEnd  | ProcessCode |
|:---------:|:----:|:---------:|:---------:|:-----------:|
| 103502090 | 6900 |  2-Jan-19 |  2-Jan-19 |    START    |
| 103502090 | 6900 |  1/2/2019 |  1/2/2019 |     END     |
| 103502090 | 6950 |  2-Jan-19 |  2-Jan-19 |    START    |
| 103502090 | 6950 |  2-Jan-19 |  2-Jan-19 |     END     |
| 103502090 | 7000 |  3-Jan-19 |  3-Jan-19 |    START    |
| 103502090 | 7000 |  3-Jan-19 |  3-Jan-19 |     END     |
| 103502090 | 7050 |  4-Jan-19 |  4-Jan-19 |    START    |
| 103502090 | 7050 |  4-Jan-19 |  4-Jan-19 |     END     |
| 103502090 | 7100 |  8-Jan-19 |  8-Jan-19 |    START    |
| 103502090 | 7100 |  8-Jan-19 |  8-Jan-19 |     END     |
| 103502090 | 7200 |  9-Jan-19 |  9-Jan-19 |    START    |
| 103502090 | 7200 |  9-Jan-19 |  9-Jan-19 |     END     |
| 103502090 | 7300 |  9-Jan-19 |  9-Jan-19 |    START    |
| 103502090 | 7300 |  9-Jan-19 |  9-Jan-19 |     END     |
| 103502090 | 7400 |  9-Jan-19 |  9-Jan-19 |    START    |
| 103502090 | 7400 |  9-Jan-19 |  9-Jan-19 |   PROCESS   |
| 103502090 | 7400 |  9-Jan-19 |  9-Jan-19 |    START    |
| 103502090 | 7400 |  9-Jan-19 |  9-Jan-19 |     END     |
| 103502090 | 7450 | 10-Jan-19 | 10-Jan-19 |    START    |
| 103502090 | 7450 | 10-Jan-19 | 10-Jan-19 |   PROCESS   |
| 103502090 | 7450 | 10-Jan-19 | 14-Jan-19 |    START    |
| 103502090 | 7450 | 10-Jan-19 | 14-Jan-19 |   PROCESS   |
| 103502090 | 7450 | 10-Jan-19 | 14-Jan-19 |    START    |
| 103502090 | 7450 | 10-Jan-19 | 14-Jan-19 |     END     |
| 103502090 | 7550 | 14-Jan-19 | 14-Jan-19 |    START    |
| 103502090 | 7550 | 14-Jan-19 | 14-Jan-19 |     END     |
| 103502090 | 7700 | 16-Jan-19 | 16-Jan-19 |    START    |
| 103502090 | 7700 | 16-Jan-19 | 16-Jan-19 |     END     |
| 103502090 | 7750 | 17-Jan-19 | 17-Jan-19 |    START    |
| 103502090 | 7750 | 17-Jan-19 | 17-Jan-19 |     END     |
| 103561375 | 7450 |  4-Jan-19 |  4-Jan-19 |    START    |
| 103561375 | 7450 |  4-Jan-19 |  4-Jan-19 |   PROCESS   |
| 103561375 | 7450 |  4-Jan-19 |  8-Jan-19 |    START    |
| 103561375 | 7450 |  4-Jan-19 |  8-Jan-19 |   PROCESS   |
| 103561375 | 7450 |  4-Jan-19 |  8-Jan-19 |    START    |
| 103561375 | 7450 |  4-Jan-19 |  8-Jan-19 |     END     |
| 103561375 | 7550 |  8-Jan-19 |  8-Jan-19 |    START    |
| 103561375 | 7550 |  8-Jan-19 |  8-Jan-19 |     END     |
| 103561375 | 7700 |  9-Jan-19 |  9-Jan-19 |    START    |
| 103561375 | 7700 |  9-Jan-19 |  9-Jan-19 |     END     |
| 103561375 | 7750 | 10-Jan-19 | 10-Jan-19 |    START    |
| 103561375 | 7750 | 10-Jan-19 | 10-Jan-19 |     END     |
| 103561454 | 6106 | 31-Jan-19 | 31-Jan-19 |    START    |
| 103561454 | 6106 | 31-Jan-19 | 31-Jan-19 |     END     |
| 103561454 | 6111 |  4-Feb-19 |  4-Feb-19 |    START    |
| 103561454 | 6111 |  4-Feb-19 |  4-Feb-19 |     END     |
| 103561454 | 6900 |  4-Feb-19 |  4-Feb-19 |    START    |
| 103561454 | 6900 |  4-Feb-19 |  4-Feb-19 |     END     |
| 103561454 | 6950 |  4-Feb-19 |  4-Feb-19 |    START    |
| 103561454 | 6950 |  4-Feb-19 |  4-Feb-19 |     END     |
| 103561454 | 7000 |  4-Feb-19 |  4-Feb-19 |    START    |
| 103561454 | 7000 |  4-Feb-19 |  4-Feb-19 |     END     |
| 103561454 | 7050 |  5-Feb-19 |  5-Feb-19 |    START    |
| 103561454 | 7050 |  5-Feb-19 |  5-Feb-19 |     END     |
| 103561454 | 7100 |  6-Feb-19 |  6-Feb-19 |    START    |
| 103561454 | 7100 |  6-Feb-19 |  6-Feb-19 |     END     |
| 103561454 | 7200 |  9-Feb-19 |  9-Feb-19 |    START    |
| 103561454 | 7200 |  9-Feb-19 |  9-Feb-19 |     END     |
| 103561454 | 7300 |  9-Feb-19 |  9-Feb-19 |    START    |
| 103561454 | 7300 |  9-Feb-19 |  9-Feb-19 |     END     |
| 103561454 | 7400 |  9-Feb-19 |  9-Feb-19 |    START    |
| 103561454 | 7400 |  9-Feb-19 |  9-Feb-19 |     END     |
| 103561454 | 7450 | 11-Feb-19 | 11-Feb-19 |    START    |
| 103561454 | 7450 | 11-Feb-19 | 11-Feb-19 |   PROCESS   |
| 103561454 | 7450 | 11-Feb-19 | 14-Feb-19 |    START    |
| 103561454 | 7450 | 11-Feb-19 | 14-Feb-19 |     END     |
| 103561454 | 7550 | 14-Feb-19 | 14-Feb-19 |    START    |
| 103561454 | 7550 | 14-Feb-19 | 14-Feb-19 |     END     |
| 103561454 | 7700 | 16-Feb-19 | 16-Feb-19 |    START    |
| 103561454 | 7700 | 16-Feb-19 | 16-Feb-19 |     END     |
| 103561454 | 7750 | 18-Feb-19 | 18-Feb-19 |    START    |
| 103561454 | 7750 | 18-Feb-19 | 18-Feb-19 |     END     |

目标是:

对于每个订单,以及每个订单中的每个步骤,计算它的排队时间,这是从上一步的LAST END开始的时间DATE 到当前步骤的 FIRST START DATE(此步骤排队等待执行的时间) .

So basically, for each row Order and Step combination, I need to find the last END date (when ProcessCode = END) and the first START date (when ProcessCode = START). Then, subtract those two and report back the value.

我试过:

SELECT
    Order,
    Step,
    (MAX(StepEnd) OVER PARTITION BY (Order, Step) - LAG(MIN(StepStart) OVER PARTITION BY (Order, Step), 1, null)) OVER PARTITION BY (
    Order, Step) AS QueueTime

FROM
    thetable

但不断收到与缺少右括号相关的错误。

我如何才能编写查询来获得结果,例如,步骤 7450 将是 1。 (这些实际上是真实数据库中的 datetime 字段,但是当我编辑一些结果时它变成了日期)

关于 over partition by 的括号语法有点错误,应该是:

MAX("StepEnd") OVER (PARTITION BY "Order", "Step")
MIN("StepStart") OVER (PARTITION BY "Order", "Step")

我已经尝试修正你的说法,见下文:

SELECT
    "Order",
    "Step", 
    MAX("StepEnd") -
    LAG(MIN("StepStart"), 1, NULL) OVER (ORDER BY MIN("StepStart")) AS QueueTime
    FROM
  Table1
group by "Order","Step"

您可以在 fiddle 中查看我的结果。

可以找到 Lag 函数的一些有用示例 here。似乎它总是需要一个 order by.

我认为您需要使用 MINMAX 分析函数,如下所示。

SELECT
    Order,
    Step,
    MAX(StepEnd) OVER PARTITION BY (Order, Step) 
    - MIN(StepStart) OVER PARTITION BY (Order, Step) AS QueueTime
    FROM
    thetable

干杯!!