我有一个时间/持续时间对表。时间间隔为15分钟,可能会有间隔。持续时间为5分钟到15分钟之间的值:
slot_ts | duration
------------------- |----------
2019-01-28 07:45:00 | 00:05:00
2019-01-28 08:00:00 | 00:10:00
2019-01-28 08:15:00 | 00:10:00
2019-01-28 08:30:00 | 00:10:00
2019-01-28 08:45:00 | 00:15:00
2019-01-28 09:30:00 | 00:15:00
2019-01-28 09:45:00 | 00:15:00
2019-01-28 10:00:00 | 00:15:00
2019-01-28 10:15:00 | 00:15:00
2019-01-28 10:30:00 | 00:15:00
2019-01-28 11:00:00 | 00:15:00
2019-01-28 11:15:00 | 00:15:00
2019-01-28 11:30:00 | 00:10:00
2019-01-28 11:45:00 | 00:15:00
2019-01-28 12:00:00 | 00:15:00
请注意8:45到9:30之间的时间间隔。还有10:30到11:00。
该概念位于每个单独的插槽(涵盖15分钟的时间),所示的持续时间是该插槽中的可用时间。因此,例如7:45插槽在该插槽中仍有5分钟可用(这意味着10分钟已用完)。如果缺少15分钟的时间段,则表示该时间段没有可用时间。因此,例如9:00、9:15、10:45时段没有可用时间。
我想为每个根据某些条件重置运行时长的时隙生成一个运行时长。
如果满足以下任一条件,则需要重置运行时间:
图片胜于文字,所以这是我所寻找的示例:
slot_ts | duration | running_duration
------------------- |----------|------------------
2019-01-28 07:45:00 | 00:05:00 | 00:15:00
2019-01-28 08:00:00 | 00:10:00 | 00:20:00
2019-01-28 08:15:00 | 00:10:00 | 00:20:00
2019-01-28 08:30:00 | 00:10:00 | 00:25:00
2019-01-28 08:45:00 | 00:15:00 | 00:15:00
2019-01-28 09:30:00 | 00:15:00 | 01:15:00
2019-01-28 09:45:00 | 00:15:00 | 01:00:00
2019-01-28 10:00:00 | 00:15:00 | 00:45:00
2019-01-28 10:15:00 | 00:15:00 | 00:30:00
2019-01-28 10:30:00 | 00:15:00 | 00:15:00
2019-01-28 11:00:00 | 00:15:00 | 00:40:00
2019-01-28 11:15:00 | 00:15:00 | 00:25:00
2019-01-28 11:30:00 | 00:10:00 | 00:10:00
2019-01-28 11:45:00 | 00:15:00 | 00:30:00
2019-01-28 12:00:00 | 00:15:00 | 00:15:00
请注意,在我的实际示例中,此表将在6个月的跨度内保存这些“可用广告位”值,而不是本示例中的7:45到正午跨度 >
我做有一个有效的查询,但它使用了2个子选择和2个窗口功能。在我的真实示例中,我将针对成千上万的行进行查询,并且这需要尽可能地瞬时运行。
这是我现有的查询,您能做得更好吗?
SELECT
slot_ts,
duration,
COALESCE(
(
SELECT SUM(duration)
FROM available_slots
WHERE slot_ts >= x.slot_ts
AND slot_ts <=
(
SELECT slot_ts AS last_ts
FROM
(
SELECT *,
NOT COALESCE(lead(slot_ts) OVER (ORDER BY slot_ts) = slot_ts + '00:15:00', FALSE) AS cur_row_stop,
NOT COALESCE(lead(slot_ts) OVER (ORDER BY slot_ts) = slot_ts + '00:15:00', FALSE) OR duration < '00:15:00' AS prev_row_stop
FROM available_slots
) z
WHERE (cur_row_stop AND slot_ts = x.slot_ts) OR (prev_row_stop AND slot_ts > x.slot_ts)
ORDER BY slot_ts LIMIT 1
)
), duration) AS running_duration
FROM available_slots AS x
ORDER BY slot_ts ASC;
这是上面的表架构和查询的sql fiddle。