使用附加约束解决时间序列数据的差距和离群(PostgreSQL)

时间:2018-04-04 22:16:55

标签: postgresql time-series postgis window-functions gaps-and-islands

我认为这是一个差距和群岛问题,但我的差距实际上是由逻辑和约束而不是缺少数据来定义的。我也使用时间序列样式数据而不是整数ID,所以我发现的许多例子似乎都不适用 - 或者我不知道如何。

我正在使用PostgreSQL和PostGIS扩展,并拥有以下数据库表:

create table event
(
    id uuid not null,
    organisation_id uuid not null,
    asset_id uuid not null,
    time timestamp with time zone not null,
    data jsonb not null,
    location extensions.geography(Point,4326),
    special_location boolean,
    constraint event_pkey
        primary key (id),
    constraint event_organisation_id_fk
        foreign key (organisation_id) references organisation,
    constraint event_asset_id_fk
        foreign key (asset_id) references asset
);

create unique index event_id_uindex on event (id);

create index event_location_index on event USING GIST (location);

我正在尝试编写一个查询来检索指定asset_id的会话列表,其中会话开始和/或在查询中指定的最小和最大日期时间之间结束。

e.g.
For <asset_id> get me all trips between <TimeA> and <TimeB>.

StartTime1, StartLocation1, EndTime1, EndLocation1
StartTime2, StartLocation2, EndTime2, EndLocation2
StartTime3, StartLocation3, EndTime3, EndLocation3
StartTime4, StartLocation4, EndTime4, EndLocation4

事件记录中没有任何内容可以将它们单独列为会话开始或会话结束事件。相反,以下规则适用:

  • 当资产的位置距离上一个会话的EndLocation“M”米时,会话被视为开始。

  • 如果指定的asset_id没有以前的会话,则使用资产的第一个已知位置作为伪EndLocation进行比较。

  • 会话的StartLocation应报告为上一个会话的EndLocation,而不是移动'M'米后的位置。

  • 在两个会话之间可能会发生移动,但如果车辆移动距离前一个会话的EndLocation不到“M”米,那么可以忽略这一点。即没有移动的总和,距离应该是从前一个EndLocation飞过的乌鸦。

  • 当资产在'T'时间内移动超过'M'时,会话被认为已经结束,其中'T'时间实际上将被指定为两个值...'T的一个值'如果资产的'special_location'字段设置为true,则使用'。如果'special_location'字段设置为false,则使用'T'的另一个值。即如果资产位于特殊地点,那么旅行将比资产位于未知(非特殊)地点的时间更早结束。

  • 很高兴但没有显示停止...... 会话的StartLocation应该是上一个会话的EndLocation(如上所述),但理想情况下我们应该能够通过以下方式允许丢失事件在查询中指定'X'米的值。如果资产在前一个会话的EndLocation的“X”米范围内,那么前一个会话的EndLocation应该用作下一个会话的StartLocation。否则,为会话的第一个事件记录的实际位置应该用作下一个会话的StartLocation。

我意识到上述内容很复杂,对于单个Stack Overflow问题可能太多了。如果您认为这一点,那么我仍然非常感谢建议和示例,这些建议和示例展示了如何实现上述部分内容和/或我应该阅读的主题。 说实话,有人确认在单个查询中是否可以进行上述操作将是一个开始!

我在考虑上述方法的过程中学到并尝试过的主题包括:

  • PostgreSQL窗口函数

  • 示例'差距和群岛'问题。我已经尝试了很多这样的例子,但是没有很多例子使用时间而不是整数ID。此外,我的差距是由约束而不是数据中的实际差距来定义的。示例起点是:

    https://stackoverflow.com/a/24101979/9599047

    https://dba.stackexchange.com/a/167069

  • 这是我第一次使用PostGIS,我至少能够使用ST_Distance计算距离,并且查询如下:

    SELECT ST_Distance(location :: geography,lag(location :: geography,1)OVER(ORDER BY time ASC))作为距事件的距离;

0 个答案:

没有答案