检索连接列车的SQL查询

检索连接列车的SQL查询,sql,Sql,我有一个数据库,包含很多不同的火车的火车时间。它看起来像这样: 表1 车站id车站名称 等 表2 车站名称到发车次 等 我知道如何检索给定列车的发车时间,但如果我想检索包含基于用户选择的出发站和到达站的多个连接列车的旅行计划,我将如何继续 有人想从伦敦到曼彻斯特,但这条路线没有直达列车,所以他必须在利物浦换乘i次列车。如何查询数据库以获得此结果 我希望有人能帮我解决这个问题,因为我找不到解决方案。我有点不确定表2中有什么信息。目前,我假设表2包含出发时间和目的站(dest_station_nam

我有一个数据库,包含很多不同的火车的火车时间。它看起来像这样:

表1

车站id车站名称 等

表2

车站名称到发车次 等

我知道如何检索给定列车的发车时间,但如果我想检索包含基于用户选择的出发站和到达站的多个连接列车的旅行计划,我将如何继续

有人想从伦敦到曼彻斯特,但这条路线没有直达列车,所以他必须在利物浦换乘i次列车。如何查询数据库以获得此结果


我希望有人能帮我解决这个问题,因为我找不到解决方案。

我有点不确定表2中有什么信息。目前,我假设表2包含出发时间和目的站(dest_station_name)

因为你无法提前知道你要跳多少次,所以你可能会想写一系列这些,每一个都有不同的火车跳数。运行1个跃点并查找没有返回的数据。如果未返回任何内容,请运行2-hop查询。如果没有返回任何内容,请运行3跃点查询,依此类推

编辑格式


注:如其他答案和评论所述:这不能用于保证最短路径。这可用于查找跳数最少的路径。例如,我写的技术建议从纽约到华盛顿特区,途经纽约到洛杉矶,即使纽约到新泽西州特伦顿,宾夕法尼亚州兰彻斯特,再到华盛顿特区都可以

这不能简化为简单的SQL查询。或者是一个复杂的问题:)

你想解决这个问题

您将需要使用站点作为顶点,以及顶点之间表示从一个站点到另一个站点的可能旅程的路径来构建图形(请注意,您将有许多从一个节点到另一个节点的路径,由出发时间设置关键帧)。每条路径的重量是它(旅程)的持续时间

然后,使用Wikipedia链接建议的算法之一解决最短路径问题,要记住,在火车开往N+1站之前,必须加上在N站等待的费用


听起来像一个有趣的黑客

我怀疑你偶然发现了一个特别困难的问题,可能没有任何真正的答案。使用一个甚至多个查询可能不可能。假设用户选择a站到B站作为行程

  • 找到所有从A开始到B结束的火车。如果你找到了,你可以停下来
  • 如果没有找到所有在A开始的列车
  • 对于每个车站S1、S2、…、Sn,在查询从Sx到B的列车时,显示从a端开始的列车。如果您找到一列列车,则停止。但是,如果不是,你必须重复。在这一点上,您必须小心,不要以循环结束。那就是你从a-E,然后E-F,然后F-a找到一列火车
  • 您可能需要使用这样的递归函数(注意,这不是完全经过考虑的):


    我不认为你真的需要一个最短路径的解决方案

    通常网站知道城市间最多2条火车路线。通常没有更多的了。 如果用户希望使用其他路线,则您有一个“旅行路线”字段


    因此,您只需将路由连接在一个路径中。

    我认为解决此问题的方法需要实现某种搜索算法-它不可能通过简单的查询来解决。你应该在一个结构中加载你的列车时间,然后寻找从a到B的所有可能的连接

    当在给定参数范围内找到所有可能的路线时(假设您知道计划行程的日期),如果您存储车票成本信息、最少的火车转辙次数等,您应该根据几个标准对它们进行排序,如最短行程、最快行程、最便宜行程。。。然后显示最有利的结果


    听起来这是一个有趣的项目。你本可以给我一个周末新爱好项目的主意;)

    对于给定完全未知数据的问题,找到最佳解决方案确实远远超出了SQL的能力。也就是说,从理论上讲,最快的路线可能是乘坐数千次列车换乘,而可能的组合总数远远超出任何计算机的处理能力

    但在实践中,我认为可以肯定地说,换车次数少的旅行几乎总是比停站次数多的旅行快,而且旅行者可能更喜欢换车次数少的旅行,而不是总行程略短的旅行,因为这样可以避免换车的麻烦和因延误而错过火车的危险。我不知道你们的铁路系统是什么样的(甚至不知道你们来自哪里),但我猜大部分行程都可以通过少量的列车换乘来完成,可能很少超过2次,对吧

    所以大卫·奥尼尔的解决方案基本上是正确的,尽管我认为他提出的问题有点困惑。他没有指定出发站,他似乎认为列车号在整个行程中保持不变,也许最重要的是,他将时间计算为行程时间的总和。当然,对旅行者来说,重要的是出发和到达之间的总时间,而不仅仅是在火车上的时间。在火车上10分钟,在车站等下一班火车4小时,在第二班火车上再等10分钟,是4小时20分钟,而不是20分钟。哦,而且他似乎没有保证换乘的火车在第一列火车到达之前不会离开。如果另一列火车在你到达前十分钟开出,换乘对你没有什么好处

    所以我认为真正的问题应该是这样的:

    哦,你对书中内容的描述
    select t1.station_name, t2.station_name, t3.station_name, 
      t4.station_name, t5.station_name,  
      sum(t2.arrival - t1.departure + /*the rest of them */) as total_time from table2 t1
    join table2 t2 on t1.dest_station_name = t2.station_name 
      and t1.train_number = t2.train_number
    join table2 t3 on t2.dest_station_name = t3.station_name 
       and t2.train_number = t3.train_number
    join table2 t4 on t3.dest_station_name = t4.station_name 
       and t3.train_number = t4.train_number
    join table2 t5 on t4.dest_station_name = t5.station_name 
       and t4.train_number = t5.train_number
    where t5.station_name = :goal_station
    order by total_time desc;
    
    journey(A, B)
          if A = B then return empty journey else
          query for trains that go from A to B, if found return the one step journey
          else
              query for all trains that start at A
              for each endpoint of trains that start at A => E
                   rest = journey(E, B)
              return A-E+rest
    
    Trip (train_number, departure_station_id, arrival_station_id, departure_time, arrival_time)
    
    Station (station_id, station_name) 
    
    select t1.train_number, t1.arrival_time-t1.departure_time as time
    from trip t1
    where t1.departure_station_id=?station_from
    and t1.arrival_station_id=?station_to
    order by time
    
    select t1.train_number, t2.train_number, t2.arrival_time-t1.departure_time as time
    from trip t1
    join trip t2 on (t2.departure_station_id=t1.arrival_station_id
    and t2.departure_time>t1.arrival_time)
    where t1.departure_station_id=?station_from
    and t2.arrival_station_id=?station_to
    order by time
    
    select t1.train_number, t2.train_number, t3.train_number, t3.arrival_time-t1.departure_time as time
    from trip t1
    join trip t2 on (t2.departure_station_id=t1.arrival_station_id
    and t2.departure_time>t1.arrival_time)
    join trip t3 on (t3.departure_station_id=t2.arrival_station_id
    and t3.departure_time>t2.arrival_time)
    where t1.departure_station_id=?station_from
    and t3.arrival_station_id=?station_to
    order by time