从有序列表构建对

时间:2016-12-09 13:27:23

标签: sql postgresql

我正在玩火车时间表并考虑在时间之间建立站点之间的连接。

让我们举个例子:

Trip I:  A (t1) ------------> B (t3) ------------> E (t5)
Trip II:          C (t2) ------------> D (t4) ---> E (t6)

我们有5站(AE),其中列车在ti时间停靠,有两次不同的行程(从AE到{{ 1}}和B E C to D`)。

时间表看起来像这样(在数据库的角度来看,还有一个技术标识符):

though

我想建立一个站点之间的连接,例如(让我们不考虑火车在车站停靠的时间为了简单起见):

 --------------------
| Trip | Stop | Time |
 --------------------
| I    | A    | t1   |
| I    | B    | t3   |
| I    | E    | t5   |
| II   | C    | t2   |
| II   | D    | t4   | 
| II   | E    | t6   | 
 --------------------

我已经在内存中使用了一些代码:

  1. 按行程分组,
  2. 按时间排序,
  3. 在滑动窗口中取2-by-2元素。
  4. 然而,它很简单但效率不高。

    这就是为什么我想知道它是否可以用SQL表达。 是吗?

    你会怎么做?

    我使用PostgreSQL进行测试,但我对轮廓比对特定数据库的确切实现更感兴趣。

1 个答案:

答案 0 :(得分:2)

第一个我为每个旅行分区生成一个rownumber,然后在row_number + 1 = row_number上自我加入

每次行程的每一行,引擎将按时间顺序分配一个数字1-N。这允许我们简单地自己加入row_number + 1。

这可能是一个问题,如果时间只是时间而且你在2300离开并到达0100或者旅行时间跨度很长。我也在这里假装军事时间。如果它是11:00和1:00那么我们也可能遇到问题。

由于每个编号都会重新开始,因此我们也需要加入此行程。

WITH CTE As (
SELECT A.*, row_Number() over (partition by trip Order by time asc) RN FROM TIME A)

SELECT A.Stop, A.Time, B.Stop, B.Time
FROM CTE A 
INNER JOIN CTE B 
  on A.RN+1 = B.RN
 and A.trip = B.Trip