1

很抱歉,如果以前在这里问过这个问题,但我似乎找不到。我一直在寻找如何按小时求和,但我的问题是关于在另一列中定义的时间戳之间的 SUM 和 COUNT。

我有一张名为incoming_orders的表:它显示了预期的目的地,以及传入订单的时间戳。

我有第二个表,名为schedule_output:它显示每个目的地的每个预定输出时刻。

我有第三张表,名为outcoming_orders:它显示了实际目的地以及传出订单的时间戳。

因此,数据可能是:

--Incoming_orders:
Destination  Timestamp
ROUTE B      14/03/2018 7:48:00 
ROUTE A      14/03/2018 7:58:00
ROUTE A      14/03/2018 12:48:00
ROUTE C      14/03/2018 13:28:00

--Scheduled_Output
ROUTE A      14/03/2018 8:00:00
ROUTE A      14/03/2018 11:00:00
ROUTE A      14/03/2018 12:00:00
ROUTE A      14/03/2018 17:00:00    
ROUTE B      14/03/2018 8:00:00
ROUTE B      14/03/2018 10:00:00
ROUTE B      14/03/2018 12:00:00
ROUTE C      14/03/2018 07:00:00 
ROUTE C      14/03/2018 14:00:00 
ROUTE C      14/03/2018 17:00:00 

--Which would lead to the following outgoing_orders:
ROUTE A      14/03/2018 8:00:00
ROUTE B      14/03/2018 8:00:00 
ROUTE C      14/03/2018 14:00:00
ROUTE A      14/03/2018 17:00:00

现在,我想检查 07:58 到路由 A 的传入订单实际上是否进入了路由 A 08:00 的输出周期。我正在考虑创建一个这样的表来显示它:

Destination output moment   expected_output actual_output   diff
Route A     8:00            1               1               0
Route A     11:00           0               0               0
Route A     12:00           0               0               0
Route A     17:00           1               1               0

但问题是:如何计算expected_output列?如何将 12:48 路由 A 的传入订单分组到 12:00-17:00 组?它应该计算预定输出时刻之间的所有订单,但我不确定如何完成。

我可以 CEIL、FLOOR 或 ROUND 到最接近的 schedule_output 值吗?或者我可以以某种方式在行 n 和 n+1 之间进行行数吗?或者还有其他更简单的方法吗?

4

1 回答 1

2

我认为通过这种方式或多或少地确定预定输出的先前时间,获取时间间隔是最简单的:

SELECT destination,
       time_stamp,
       ( SELECT max( time_stamp ) 
         FROM SCHEDULED_OUTPUT t1
         WHERE t.destination = t1.destination
           AND t1.time_stamp < t.time_stamp
        ) as previous_time_stamp
FROM SCHEDULED_OUTPUT t
order by 1,2

或者使用解析函数以更紧凑的形式:

SELECT destination,
       time_stamp,
       lag( time_stamp ) over (partition by destination order by time_stamp )
       as previous_time_stamp
FROM SCHEDULED_OUTPUT t
order by 1,2

演示:http ://sqlfiddle.com/#!4/c7bc9/1

| DESTINATION |            TIME_STAMP |   PREVIOUS_TIME_STAMP |
|-------------|-----------------------|-----------------------|
|     ROUTE A | 2018-03-14 08:00:00.0 |                (null) |
|     ROUTE A | 2018-03-14 11:00:00.0 | 2018-03-14 08:00:00.0 |
|     ROUTE A | 2018-03-14 12:00:00.0 | 2018-03-14 11:00:00.0 |
|     ROUTE A | 2018-03-14 17:00:00.0 | 2018-03-14 12:00:00.0 |
|     ROUTE B | 2018-03-14 08:00:00.0 |                (null) |
|     ROUTE B | 2018-03-14 10:00:00.0 | 2018-03-14 08:00:00.0 |
|     ROUTE B | 2018-03-14 12:00:00.0 | 2018-03-14 10:00:00.0 |
|     ROUTE C | 2018-03-14 07:00:00.0 |                (null) |
|     ROUTE C | 2018-03-14 14:00:00.0 | 2018-03-14 07:00:00.0 |
|     ROUTE C | 2018-03-14 17:00:00.0 | 2018-03-14 14:00:00.0 |

接下来可以将上述结果集加入 INCOMING_ORDERS 以计算计数:

SELECT x.destination, x.time_stamp as output_moment,
       count( y.DESTINATION ) as expected_output 
FROM (
   SELECT destination,
          time_stamp,
          lag( time_stamp ) over (partition by destination order by time_stamp )
          as previous_time_stamp
   FROM SCHEDULED_OUTPUT t
) x
LEFT JOIN INCOMING_ORDERS y
ON x.DESTINATION =  y.DESTINATION
AND y.TIME_STAMP <= x.TIME_STAMP
AND ( y.TIME_STAMP > x.previous_time_stamp OR x.previous_time_stamp IS NULL )
GROUP BY x.destination, x.time_stamp
ORDER BY 1,2

演示:http ://sqlfiddle.com/#!4/c3958/2

| DESTINATION |         OUTPUT_MOMENT | EXPECTED_OUTPUT |
|-------------|-----------------------|-----------------|
|     ROUTE A | 2018-03-14 08:00:00.0 |               1 |
|     ROUTE A | 2018-03-14 11:00:00.0 |               0 |
|     ROUTE A | 2018-03-14 12:00:00.0 |               0 |
|     ROUTE A | 2018-03-14 17:00:00.0 |               1 |
|     ROUTE B | 2018-03-14 08:00:00.0 |               1 |
|     ROUTE B | 2018-03-14 10:00:00.0 |               0 |
|     ROUTE B | 2018-03-14 12:00:00.0 |               0 |
|     ROUTE C | 2018-03-14 07:00:00.0 |               0 |
|     ROUTE C | 2018-03-14 14:00:00.0 |               1 |
|     ROUTE C | 2018-03-14 17:00:00.0 |               0 |

这个条件:

AND y.TIME_STAMP <= x.TIME_STAMP
AND ( y.TIME_STAMP > x.previous_time_stamp OR x.previous_time_stamp IS NULL )

告诉如果在 8:00:00 下订单并且路线同时在 8:00:00 开始,那么这个订单仍然分配给这个“开始”路线。如果这是不可能的(即 - 必须在路线开始的确切时间下订单时将订单分配给下一条路线),然后将条件更改为:

AND y.TIME_STAMP < x.TIME_STAMP
AND ( y.TIME_STAMP >= x.previous_time_stamp OR x.previous_time_stamp IS NULL )
于 2018-03-14T16:53:59.123 回答