Postgres匹配到最近的时间

时间:2014-08-03 03:19:05

标签: postgresql

我在Ubuntu上使用psql(9.3.5)尝试加入两个数据集:

第一组包含有关离开节点i后节点j的到达时间的信息。我试图将其与j处的最近预定到达时间进行匹配,然后计算该预定事件的i和j之间的距离(d)的差异。这种差异取决于时间表。

我当前的尝试涉及第一个(原始)表和schedule(to_match)表之间的两个连接(在i和j上),并使用min()返回事件时间和计划之间的差异。

        select r.i, r.j, r.time, second.schedule, 
min((r.time - second.schedule)) as diff_from_schedule, 
    round(second.d - first.d) as d_diff
    from raw r
    inner join to_match first on r.i = first.key
    inner join to_match second on r.j = second.key
    group by r.i, r.j, r.time, second.schedule, d_diff

这不会返回值之间的最近/最小差异。事实上,有些相当遥远。

i           j           time    sched   diff_from_schedule  d_diff
12598       14013       57233   20340   36893   2951
12598       14013       25829   26640   811     3015
12598       14013       53927   66780   12853   2951
12598       14013       66236   18180   48056   2951

此外,原始表中有24条记录,但它返回to_match表中的每个值。我正在使用内部联接,如果它不返回左表中的记录?有没有人有想法?

带有样本数据的PGDump位于此[Gist] {https://gist.github.com/laidig/37fcd396009cabf5c1e8}中。非常感谢您的帮助!

1 个答案:

答案 0 :(得分:0)

这里有一个棘手的问题,因为您的数据不允许导出单一解决方案。首先是最接近的“解决方案”,但请继续阅读以获取详细信息:

SELECT DISTINCT diffs.*, round(dest.d - src.d) AS d_diff
FROM
   (SELECT DISTINCT ON (r.i, r.j, r.time)
      r.i, r.j, r.time, dest.schedule, min(abs(r.time - dest.schedule)) AS diff
    FROM raw r
    JOIN to_match dest ON r.j = dest.key
    GROUP BY r.i, r.j, r.time, dest.schedule
    ORDER BY r.i, r.j, r.time, diff ASC) AS diffs
JOIN to_match dest ON dest.key = diffs.j AND dest.schedule = diffs.schedule
JOIN to_match src ON src.key = diffs.i
ORDER BY diffs.i, diffs.j, diffs.time

子查询针对raw数据和to_match的每个组合计算最小时差,然后选择每个raw记录具有最佳匹配的记录。外部查询然后将d_diff添加到其中。

但是您的数据模型存在缺陷。对于key表中的每个to_match值,您有两个d值。对于j这不是问题,因为您可以对schedule值进行过滤,但是您没有i的信息,因此raw的每条记录都会获得两次点击1}}数据(或d值的不同i值的数量。因此,上述结果是最好的结果。

您可能希望更仔细地分析数据模型并将to_match规范化至至少1个表,添加有关计划的更多信息,以便您可以唯一地匹配i和{{1}到时间表。