我很抱歉以前在这里问过这个问题,但我似乎无法找到它。我一直在寻找如何每小时求和,但我的问题是关于在另一列中定义的时间戳之间的SUM和COUNT。
我有一个名为 incoming_orders 的表:它显示了预期的目的地,以及传入订单的时间戳。
我有一个名为 scheduled_output 的第二个表:它显示每个目的地的每个预定输出时刻。
我有第三个名为 outgoing_orders 的表格:它显示了实际目的地的方式以及传出订单的时间戳。
所以,数据可能是:
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
现在,我想检查路由A的07:58的传入订单实际上是否为路由A的08:00的输出周期。我正在考虑创建一个这样的表来显示它:
Container
但问题是:如何计算 expected_output 列?如何将收到的订单分组到12:48的路线A到12:00-17:00组?它应该计算预定输出时刻之间的所有顺序,但我不知道如何实现。
我可能CEIL,FLOOR或ROUND到最接近的scheduled_output值吗?或者我可以以某种方式在行n和n + 1之间进行行数计数?或者还有另一种更简单的方法吗?
答案 0 :(得分: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 )