根据多种条件与 DB2 结果聚合
Aggregates with DB2 results based on multiple conditions
我正在尝试根据多种因素找出聚合 DB2 结果和分组的最佳方法。
目前我有这个查询:
SELECT
T1.VEHICLE,
T2.VEHICLE_ID,
T3.WORK_ORDER_ID,
T3.JOB_CREATION,
T5.JOB_STATUS,
T4.JOB_STATUS_TIME
FROM SCHEMA.VEHICLE T1
INNER JOIN SCHEMA.VEHICLE_TO_WORK_ORDER T2
ON T1.VEHICLE_ID = T2.VEHICLE_ID
INNER JOIN SCHEMA.WORK_ORDER T3
ON T2.WORK_ORDER_ID = T3.WORK_ORDER_ID
INNER JOIN SCHEMA.WORK_ORDER_TO_JOB_STATUS T4
ON T3.WORK_ORDER_ID = T4.WORK_ORDER_ID
INNER JOIN SCHEMA.JOB_STATUS T5
ON T4.JOB_STATUS_ID = T5.JOB_STATUS_ID;
returns 这些结果,从数据的角度来看是正确的:
VEHICLE VEHICLE_ID WORK_ORDER_ID JOB_CREATION JOB_STATUS JOB_STATUS_TIME
------------------------------------------------------------------------------------------------------------------
VEHICLE 6 6 12345 2019-09-25 00:00:09.426178 CREATED 2019-09-25 00:00:09.469059
VEHICLE 6 6 12345 2019-09-25 00:00:09.426178 ACTIVE 2019-09-25 13:40:00.981891
VEHICLE 6 6 12345 2019-09-25 00:00:09.426178 COMPLETED 2019-09-25 13:45:02.748800
VEHICLE 7 7 54321 2019-09-26 00:00:09.426178 CREATED 2019-09-26 00:00:09.469059
VEHICLE 7 7 54321 2019-09-26 00:00:09.426178 ACTIVE 2019-09-26 13:40:00.981891
VEHICLE 7 7 54321 2019-09-26 00:00:09.426178 PAUSED 2019-09-26 14:40:02.748800
VEHICLE 7 7 54321 2019-09-26 00:00:09.426178 ACTIVE 2019-09-26 14:45:09.469059
VEHICLE 7 7 54321 2019-09-26 00:00:09.426178 COMPLETED 2019-09-26 14:50:00.981891
VEHICLE 3 3 12346 2019-09-27 00:00:09.426178 OPEN 2019-09-27 13:40:02.748800
VEHICLE 3 3 12346 2019-09-27 00:00:09.426178 ACTIVE 2019-09-27 13:45:09.469059
VEHICLE 3 3 12346 2019-09-27 00:00:09.426178 PAUSED 2019-09-27 13:50:00.981891
VEHICLE 3 3 12346 2019-09-27 00:00:09.426178 CANCELLED 2019-09-27 13:51:02.748800
我想在这里做的是按车辆分组,并在给定的日期范围内获取该车辆的工作订单,然后总结 activity 时间或活动之间的时间,以便我可以实现聚合对于总和列(此示例有 3 辆车,每辆车只有一个工单,但我希望能够查看日期范围内的任何工单并获得相同的聚合。)
我想计算已创建的每个工作订单的数量,以及每个已完成或取消的订单的数量,但我想要的总活动时间是 job_status_time(从每个活动到暂停或活动到完成的时间,因为任务可以活动然后暂停,然后再次活动然后完成)
我希望得到与此类似的结果,但我不太清楚如何正确汇总:
VEHICLE Created Completed Cancelled Total Active Time (minutes)
------------------------------------------------------------------
6 1 1 0 5
7 1 1 0 65
3 1 0 1 5
如何按车辆对这些结果进行分组,并仍然根据 job_status
获得这些总和列和聚合时间
LUW 的 Db2
WITH
RES (VEHICLE_ID, JOB_STATUS, JOB_STATUS_TIME) AS
(
VALUES
(6, 'CREATED', TIMESTAMP('2019-09-25-00.00.09.469059'))
, (6, 'ACTIVE', TIMESTAMP('2019-09-25-13.40.00.981891'))
, (6, 'COMPLETED', TIMESTAMP('2019-09-25-13.45.02.748800'))
, (7, 'CREATED', TIMESTAMP('2019-09-26-00.00.09.469059'))
, (7, 'ACTIVE', TIMESTAMP('2019-09-26-13.40.00.981891'))
, (7, 'PAUSED', TIMESTAMP('2019-09-26-14.40.02.748800'))
, (7, 'ACTIVE', TIMESTAMP('2019-09-26-14.45.09.469059'))
, (7, 'COMPLETED', TIMESTAMP('2019-09-26-14.50.00.981891'))
, (3, 'OPEN', TIMESTAMP('2019-09-27-13.40.02.748800'))
, (3, 'ACTIVE', TIMESTAMP('2019-09-27-13.45.09.469059'))
, (3, 'PAUSED', TIMESTAMP('2019-09-27-13.50.00.981891'))
, (3, 'CANCELLED', TIMESTAMP('2019-09-27-13.51.02.748800'))
)
, A AS
(
SELECT
VEHICLE_ID, JOB_STATUS
, JOB_STATUS_TIME
, LEAD (JOB_STATUS_TIME) OVER (PARTITION BY VEHICLE_ID ORDER BY JOB_STATUS_TIME) AS JOB_STATUS_TIME_NEXT
FROM RES
)
SELECT
VEHICLE_ID
, COUNT(CASE JOB_STATUS WHEN 'CREATED' THEN 1 END) AS CREATED
, COUNT(CASE JOB_STATUS WHEN 'COMPLETED' THEN 1 END) AS COMPLETED
, COUNT(CASE JOB_STATUS WHEN 'CANCELLED' THEN 1 END) AS CANCELLED
, SUM
(
CASE JOB_STATUS WHEN 'ACTIVE' THEN
(DAYS(JOB_STATUS_TIME_NEXT) - DAYS(JOB_STATUS_TIME)) * 86400
+ MIDNIGHT_SECONDS(JOB_STATUS_TIME_NEXT) - MIDNIGHT_SECONDS(JOB_STATUS_TIME)
END
) / 60 AS ACTIVE_MINUTES
FROM A
GROUP BY VEHICLE_ID;
用于 iSeries 和 LUW 的 DB2
似乎 DB2 for iSeries(至少我的 7.3)有一个错误 - 尝试在上面的查询中使用 DAYS(JOB_STATUS_TIME_NEXT)
表达式会导致 SQLCODE = -171。我不知道是什么原因:如果是因为从 OLAP 函数获得的函数参数或其他原因...
但是,我们可以将查询改写如下:
WITH
RES (VEHICLE_ID, JOB_STATUS, JOB_STATUS_TIME) AS
(
VALUES
(6, 'CREATED', TIMESTAMP('2019-09-25-00.00.09.469059'))
, (6, 'ACTIVE', TIMESTAMP('2019-09-25-13.40.00.981891'))
, (6, 'COMPLETED', TIMESTAMP('2019-09-25-13.45.02.748800'))
, (7, 'CREATED', TIMESTAMP('2019-09-26-00.00.09.469059'))
, (7, 'ACTIVE', TIMESTAMP('2019-09-26-13.40.00.981891'))
, (7, 'PAUSED', TIMESTAMP('2019-09-26-14.40.02.748800'))
, (7, 'ACTIVE', TIMESTAMP('2019-09-26-14.45.09.469059'))
, (7, 'COMPLETED', TIMESTAMP('2019-09-26-14.50.00.981891'))
, (3, 'OPEN', TIMESTAMP('2019-09-27-13.40.02.748800'))
, (3, 'ACTIVE', TIMESTAMP('2019-09-27-13.45.09.469059'))
, (3, 'PAUSED', TIMESTAMP('2019-09-27-13.50.00.981891'))
, (3, 'CANCELLED', TIMESTAMP('2019-09-27-13.51.02.748800'))
)
, A AS
(
SELECT
VEHICLE_ID, JOB_STATUS
, JOB_STATUS_TIME
, ROWNUMBER() OVER (PARTITION BY VEHICLE_ID ORDER BY JOB_STATUS_TIME) AS RN
FROM RES
)
SELECT
A1.VEHICLE_ID
, COUNT(CASE A1.JOB_STATUS WHEN 'CREATED' THEN 1 END) AS CREATED
, COUNT(CASE A1.JOB_STATUS WHEN 'COMPLETED' THEN 1 END) AS COMPLETED
, COUNT(CASE A1.JOB_STATUS WHEN 'CANCELLED' THEN 1 END) AS CANCELLED
, SUM
(
CASE A1.JOB_STATUS WHEN 'ACTIVE' THEN
(DAYS(A2.JOB_STATUS_TIME) - DAYS(A1.JOB_STATUS_TIME)) * 86400
+ MIDNIGHT_SECONDS(A2.JOB_STATUS_TIME) - MIDNIGHT_SECONDS(A1.JOB_STATUS_TIME)
END
) / 60 AS ACTIVE_MINUTES
FROM A A1
LEFT JOIN A A2 ON A2.VEHICLE_ID = A1.VEHICLE_ID AND A2.RN = A1.RN + 1
GROUP BY A1.VEHICLE_ID;
结果是:
|VEHICLE_ID |CREATED |COMPLETED |CANCELLED |ACTIVE_MINUTES|
|-----------|-----------|-----------|-----------|--------------|
|3 |0 |0 |1 |4 |
|6 |1 |1 |0 |5 |
|7 |1 |1 |0 |64 |
我正在尝试根据多种因素找出聚合 DB2 结果和分组的最佳方法。
目前我有这个查询:
SELECT
T1.VEHICLE,
T2.VEHICLE_ID,
T3.WORK_ORDER_ID,
T3.JOB_CREATION,
T5.JOB_STATUS,
T4.JOB_STATUS_TIME
FROM SCHEMA.VEHICLE T1
INNER JOIN SCHEMA.VEHICLE_TO_WORK_ORDER T2
ON T1.VEHICLE_ID = T2.VEHICLE_ID
INNER JOIN SCHEMA.WORK_ORDER T3
ON T2.WORK_ORDER_ID = T3.WORK_ORDER_ID
INNER JOIN SCHEMA.WORK_ORDER_TO_JOB_STATUS T4
ON T3.WORK_ORDER_ID = T4.WORK_ORDER_ID
INNER JOIN SCHEMA.JOB_STATUS T5
ON T4.JOB_STATUS_ID = T5.JOB_STATUS_ID;
returns 这些结果,从数据的角度来看是正确的:
VEHICLE VEHICLE_ID WORK_ORDER_ID JOB_CREATION JOB_STATUS JOB_STATUS_TIME
------------------------------------------------------------------------------------------------------------------
VEHICLE 6 6 12345 2019-09-25 00:00:09.426178 CREATED 2019-09-25 00:00:09.469059
VEHICLE 6 6 12345 2019-09-25 00:00:09.426178 ACTIVE 2019-09-25 13:40:00.981891
VEHICLE 6 6 12345 2019-09-25 00:00:09.426178 COMPLETED 2019-09-25 13:45:02.748800
VEHICLE 7 7 54321 2019-09-26 00:00:09.426178 CREATED 2019-09-26 00:00:09.469059
VEHICLE 7 7 54321 2019-09-26 00:00:09.426178 ACTIVE 2019-09-26 13:40:00.981891
VEHICLE 7 7 54321 2019-09-26 00:00:09.426178 PAUSED 2019-09-26 14:40:02.748800
VEHICLE 7 7 54321 2019-09-26 00:00:09.426178 ACTIVE 2019-09-26 14:45:09.469059
VEHICLE 7 7 54321 2019-09-26 00:00:09.426178 COMPLETED 2019-09-26 14:50:00.981891
VEHICLE 3 3 12346 2019-09-27 00:00:09.426178 OPEN 2019-09-27 13:40:02.748800
VEHICLE 3 3 12346 2019-09-27 00:00:09.426178 ACTIVE 2019-09-27 13:45:09.469059
VEHICLE 3 3 12346 2019-09-27 00:00:09.426178 PAUSED 2019-09-27 13:50:00.981891
VEHICLE 3 3 12346 2019-09-27 00:00:09.426178 CANCELLED 2019-09-27 13:51:02.748800
我想在这里做的是按车辆分组,并在给定的日期范围内获取该车辆的工作订单,然后总结 activity 时间或活动之间的时间,以便我可以实现聚合对于总和列(此示例有 3 辆车,每辆车只有一个工单,但我希望能够查看日期范围内的任何工单并获得相同的聚合。)
我想计算已创建的每个工作订单的数量,以及每个已完成或取消的订单的数量,但我想要的总活动时间是 job_status_time(从每个活动到暂停或活动到完成的时间,因为任务可以活动然后暂停,然后再次活动然后完成)
我希望得到与此类似的结果,但我不太清楚如何正确汇总:
VEHICLE Created Completed Cancelled Total Active Time (minutes)
------------------------------------------------------------------
6 1 1 0 5
7 1 1 0 65
3 1 0 1 5
如何按车辆对这些结果进行分组,并仍然根据 job_status
获得这些总和列和聚合时间LUW 的 Db2
WITH
RES (VEHICLE_ID, JOB_STATUS, JOB_STATUS_TIME) AS
(
VALUES
(6, 'CREATED', TIMESTAMP('2019-09-25-00.00.09.469059'))
, (6, 'ACTIVE', TIMESTAMP('2019-09-25-13.40.00.981891'))
, (6, 'COMPLETED', TIMESTAMP('2019-09-25-13.45.02.748800'))
, (7, 'CREATED', TIMESTAMP('2019-09-26-00.00.09.469059'))
, (7, 'ACTIVE', TIMESTAMP('2019-09-26-13.40.00.981891'))
, (7, 'PAUSED', TIMESTAMP('2019-09-26-14.40.02.748800'))
, (7, 'ACTIVE', TIMESTAMP('2019-09-26-14.45.09.469059'))
, (7, 'COMPLETED', TIMESTAMP('2019-09-26-14.50.00.981891'))
, (3, 'OPEN', TIMESTAMP('2019-09-27-13.40.02.748800'))
, (3, 'ACTIVE', TIMESTAMP('2019-09-27-13.45.09.469059'))
, (3, 'PAUSED', TIMESTAMP('2019-09-27-13.50.00.981891'))
, (3, 'CANCELLED', TIMESTAMP('2019-09-27-13.51.02.748800'))
)
, A AS
(
SELECT
VEHICLE_ID, JOB_STATUS
, JOB_STATUS_TIME
, LEAD (JOB_STATUS_TIME) OVER (PARTITION BY VEHICLE_ID ORDER BY JOB_STATUS_TIME) AS JOB_STATUS_TIME_NEXT
FROM RES
)
SELECT
VEHICLE_ID
, COUNT(CASE JOB_STATUS WHEN 'CREATED' THEN 1 END) AS CREATED
, COUNT(CASE JOB_STATUS WHEN 'COMPLETED' THEN 1 END) AS COMPLETED
, COUNT(CASE JOB_STATUS WHEN 'CANCELLED' THEN 1 END) AS CANCELLED
, SUM
(
CASE JOB_STATUS WHEN 'ACTIVE' THEN
(DAYS(JOB_STATUS_TIME_NEXT) - DAYS(JOB_STATUS_TIME)) * 86400
+ MIDNIGHT_SECONDS(JOB_STATUS_TIME_NEXT) - MIDNIGHT_SECONDS(JOB_STATUS_TIME)
END
) / 60 AS ACTIVE_MINUTES
FROM A
GROUP BY VEHICLE_ID;
用于 iSeries 和 LUW 的 DB2
似乎 DB2 for iSeries(至少我的 7.3)有一个错误 - 尝试在上面的查询中使用 DAYS(JOB_STATUS_TIME_NEXT)
表达式会导致 SQLCODE = -171。我不知道是什么原因:如果是因为从 OLAP 函数获得的函数参数或其他原因...
但是,我们可以将查询改写如下:
WITH
RES (VEHICLE_ID, JOB_STATUS, JOB_STATUS_TIME) AS
(
VALUES
(6, 'CREATED', TIMESTAMP('2019-09-25-00.00.09.469059'))
, (6, 'ACTIVE', TIMESTAMP('2019-09-25-13.40.00.981891'))
, (6, 'COMPLETED', TIMESTAMP('2019-09-25-13.45.02.748800'))
, (7, 'CREATED', TIMESTAMP('2019-09-26-00.00.09.469059'))
, (7, 'ACTIVE', TIMESTAMP('2019-09-26-13.40.00.981891'))
, (7, 'PAUSED', TIMESTAMP('2019-09-26-14.40.02.748800'))
, (7, 'ACTIVE', TIMESTAMP('2019-09-26-14.45.09.469059'))
, (7, 'COMPLETED', TIMESTAMP('2019-09-26-14.50.00.981891'))
, (3, 'OPEN', TIMESTAMP('2019-09-27-13.40.02.748800'))
, (3, 'ACTIVE', TIMESTAMP('2019-09-27-13.45.09.469059'))
, (3, 'PAUSED', TIMESTAMP('2019-09-27-13.50.00.981891'))
, (3, 'CANCELLED', TIMESTAMP('2019-09-27-13.51.02.748800'))
)
, A AS
(
SELECT
VEHICLE_ID, JOB_STATUS
, JOB_STATUS_TIME
, ROWNUMBER() OVER (PARTITION BY VEHICLE_ID ORDER BY JOB_STATUS_TIME) AS RN
FROM RES
)
SELECT
A1.VEHICLE_ID
, COUNT(CASE A1.JOB_STATUS WHEN 'CREATED' THEN 1 END) AS CREATED
, COUNT(CASE A1.JOB_STATUS WHEN 'COMPLETED' THEN 1 END) AS COMPLETED
, COUNT(CASE A1.JOB_STATUS WHEN 'CANCELLED' THEN 1 END) AS CANCELLED
, SUM
(
CASE A1.JOB_STATUS WHEN 'ACTIVE' THEN
(DAYS(A2.JOB_STATUS_TIME) - DAYS(A1.JOB_STATUS_TIME)) * 86400
+ MIDNIGHT_SECONDS(A2.JOB_STATUS_TIME) - MIDNIGHT_SECONDS(A1.JOB_STATUS_TIME)
END
) / 60 AS ACTIVE_MINUTES
FROM A A1
LEFT JOIN A A2 ON A2.VEHICLE_ID = A1.VEHICLE_ID AND A2.RN = A1.RN + 1
GROUP BY A1.VEHICLE_ID;
结果是:
|VEHICLE_ID |CREATED |COMPLETED |CANCELLED |ACTIVE_MINUTES|
|-----------|-----------|-----------|-----------|--------------|
|3 |0 |0 |1 |4 |
|6 |1 |1 |0 |5 |
|7 |1 |1 |0 |64 |