【问题标题】:How to aggregate only neighbour records in sql?如何在sql中只聚合邻居记录?
【发布时间】:2021-07-23 16:07:30
【问题描述】:

假设我有一个名为位置的表,它包含源位置的记录以及记录该位置的时间。

id source_id ts position
1 3134 2021-02-21 20:48:08.488359 ...
2 3134 2021-02-21 20:48:09.123422 ...
... ... ... ...

ts 是时间戳的缩写,位置是 postgis 格式,但对于这个问题并不重要。

我还有另一个名为 zone 的表:

id area
1 ...
2 ...
... ...

该区域是一个 postgis 格式的多边形。

例如,我可以测试一个点是否在一个区域中

SELECT locations.source_id, zones.id, locations.ts
from locations inner join
     zones
     on ST_Contains(zones.area, locations.position);

会在什么时候告诉我哪个来源在哪个区域。

我想要的是产生以下输出的查询:

locations.source_id zones.id in_zone_time
3134 1 1 mins
3134 2 4 mins
3134 1 2 mins
... ... ...

所以它会告诉我源 3134 在区域 1 中持续了 1 分钟,之后它在区域 2 中持续了 4 分钟,然后又在区域 1 中持续了 2 分钟。

这种方式如何实现聚合?

【问题讨论】:

    标签: sql postgresql postgis aggregation


    【解决方案1】:

    您可以添加一个标志,然后将其视为间隙和孤岛问题。不清楚time是如何计算的,但思路是:

    select source_id, id, min(ts), max(ts), max(ts) - min(ts) as diff
    from (select l.source_id, z.id, l.ts,
                 row_number() over (partition by l.source_id order by l.ts) as seqnumm
                 row_number() over (partition by l.source_id, z.id order by l.ts) as seqnum_2
          from locations l inner join
               zones
               on ST_Contains(z.area, l.position)
         ) lz
    group by (seqnum - seqnum_2);
    

    这做了一些假设:

    • 所有点都在一个区域中。或者至少,您只关心区域内的点。
    • 积分一次只能在一个区域内。
    • 在区域中花费的时间是在该区域中的最早记录和最后记录之间的差异。

    所有这些都是对您问题的相当合理的解释,但可以放宽。如果您的要求不同,我建议您提出一个 问题,明确说明问题的细节。样本数据和相应的期望结果非常有帮助。

    【讨论】:

    • 非常感谢 :) 这几乎正是我想要的,但我能够对其进行修改以满足我的需要。谢谢你真棒:)
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2020-08-23
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多