选择符合规则的一对行

时间:2011-10-23 19:58:57

标签: sql

我有一个包含以下列的大表(1M行): 来源,目的地,距离。 每行定义一个链接(从A到B)。

我需要使用anoter节点找到一对之间的距离。 一个例子: 如果想找到A和B之间的距离, 如果我找到一个节点x并且有: x - >一个 x - >乙 我可以添加这些距离并且具有A和B之间的距离。 我的问题: 如何找到所有节点(例如x)并获得它们与(A和B)的距离? 我的目的是选择距离的最小值。

P.s:A和B只是一个连接(我需要为100K连接做这件事)。 谢谢!

6 个答案:

答案 0 :(得分:1)

正如Andomar所说,你需要Dijkstra的算法,这里是T-SQL中该算法的链接:T-SQL Dijkstra's Algorithm

答案 1 :(得分:0)

假设您想从A-B获取具有许多中间步骤的路径,则无法在纯SQL中执行无限数量的步骤。简而言之,它缺乏表现力,见http://en.wikipedia.org/wiki/Expressive_power#Expressive_power_in_database_theory。正如Andomar所说,将数据加载到一个过程和我们的Djikstra算法中。

答案 2 :(得分:0)

这听起来像traveling salesman problem

从SQL语法的角度来看:connect by prior将在使用start之后构建树,并限制它可以遍历的层数;但是,做不会保证最低限度。

答案 3 :(得分:0)

我可能会因此而被投票,但我发现这是一个有趣的问题。我希望这可以是一个更开放的讨论,因为我认为我可以从中学到很多东西。

似乎应该可以通过执行多个select语句来实现这一点 - 例如SELECT id FROM mytable WHERE source="A" ORDER BY distance ASC LIMIT 1。在while循环中包装这样的东西,并用id变量替换“A”,可以解决问题,不是吗?

例如(A是来源,B是最终目的地):

DECLARE var_id as INT
WHILE var_id != 'B'
  BEGIN
    SELECT id INTO var_id FROM mytable WHERE source="A" ORDER BY distance ASC LIMIT 1
    SELECT var_id
  END

不会有这样的工作吗? (代码很草率,但这个想法似乎很合理。)评论非常受欢迎。

答案 4 :(得分:0)

将目标连接到源,将表连接到自身。添加两个链接的距离。将其作为新链接插入左侧源,右侧目的地和总距离(如果表中尚未存在)。如果它在表格中但总距离较短,则用较短的距离更新现有行。

重复此操作,直到您没有添加到表中的新链接,并且没有更短距离的更新。您的表现在包含源和目标的每个可能组合的链接,它们之间的距离最小。看看这需要多少次重复会很有趣。

这不会跟踪源和目标之间的中间路径,但只提供最短距离。

答案 5 :(得分:0)

IIUC应该这样做,但我不确定这是否真的可行(性能方面),因为涉及大量行和CROSS JOIN

SELECT 
    t1.src AS A, 
    t1.dest AS x, 
    t2.dest AS B, 
    t1.distance + t2.distance AS total_distance
FROM
    big_table AS t1
CROSS JOIN
    big_table AS t2 ON t1.dst = t2.src
WHERE
    A = 'insert source (A) here' AND 
    B = 'insert destination (B) here'
ORDER BY
    total_distance ASC
LIMIT
    1

上述代码段适用于您有两行A-> x和x-> B但不适用于其他组合的情况(例如A-> x和B-> x) 。扩展它以覆盖所有四个组合应该是微不足道的(例如创建一个复制每一行并交换src和dest的视图)。