-1

我正在寻找是否可以在 SQL 中解决以下问题,或者我是否最好将这些值选择到我的脚本语言中并从那里进行批量更新。

有一些时间点,有一些时间间隔由时间间隔的中心和从中心开始的最大持续时间定义,所有这些时间间隔都是 10 分钟。中心可以彼此相距任何持续时间,点可以彼此相距任何持续时间。希望选择所有时间间隔,以及一个或零个点,以便每个点要么不分配,要么只分配给一个间隔。如果一个点匹配多个区间,或反之亦然,则应选择点以使点和区间中心之间的总持续时间最小化。

样本数据

interval
id centertime
1 2001-01-01 12.00     # starts at 11.50 ends at 12.10
2 2001-01-01 12.15     # starts at 12.05 ends at 12.25
3 2001-01-01 12.20     # starts at 12.10 ends at 12.30

point
id time
21 2001-01-01 12.00     
22 2001-01-01 12.11
23 2001-01-01 12.17
24 2001-01-01 12.19

期望的结果:

interval_id point_id
1 21
2 23
3 24

解释

点 21 与区间 1 的中心完全匹配,仅此而已,因此已分配。

点 23 比 3 更接近区间 2,但点 24 更接近 3,因此将区间 3 指定为点 24。

点 22 是距离间隔 2 最近的剩余点,因此已分配。

点 21 在区间 2 内,但点 22 可用且更接近,因此 21 未分配给区间且不会出现在结果中。

点 23 更接近 3,所以 22 是最接近的剩余点

4

1 回答 1

0

好的,我明白了。

它使用横向连接来计算从每个中心时间到每个点的持续时间,并将其包装在一个额外的 SELECT 中,以便使用有序窗口函数仅获得最接近的匹配。

SELECT * FROM (
    SELECT
        i.id as interval_id,
        p.id as point_id,
        p.duration,
        ROW_NUMBER() OVER (PARTITION BY i.id ORDER BY duration) AS rownumber
    FROM "interval" i
    LEFT JOIN LATERAL (
        SELECT
            p1.id,
            p1."time",
            ABS(EXTRACT(EPOCH FROM i.centertime - p1."time")) as duration
        FROM "point" p1
        WHERE p1."time"
            BETWEEN i.centertime - interval '10 minute'
            AND i.centertime + interval '10 minute'
     ) p on true)
     AS q
WHERE rownumber=1;
于 2019-07-02T16:32:48.317 回答