Mysql递归查询互连线

时间:2017-09-27 17:53:44

标签: mysql sql recursion

我有两张桌子:线条和点。线表表示两点之间的互连。

行表有:

  

idLine idStartPoint idEndPoint ...
  YL19197 YP004990 YP004991
  YL19195 YP004989 YP004990
  YL19199 YP004991 YP004992   ...

积分表有:

     idPoint  Feed ...
     YP004990   0
     YP004989   0
     YP004991   0
     .......   ...
     YP005214   1

只有idLine值,我需要遍历基于idStartPoint和idEndPoint的所有行,直到有一个点的Feed值为' 1'。

现在我做了这个(假设idLine是YL19197)

  • 搜索YL19197行并带上idStartPoint(YP004990)和idEndPoint(YP004991)
  • 生成一个查询,该查询带来连接到YL19197的两条线路(不带回YL19197):
  

从idStartPoint =' YP004990'的行中选择*和idLine<>   ' YL19197'

     

联合选择*来自idEndPoint =' YP004990'和idLine<>   ' YL19197'

     

联合选择*来自idStartPoint =' YP004991'和idLine   <> ' YL19197'

     

联合选择*来自idEndPoint =' YP004991'和idLine<>   ' YL19197'

这让我回到了两行:

idLine idStartPoint idEndPoint

YL19195 YP004989 YP004990

YL19199 YP004991 YP004992

但是我需要所有相互连接的线路,直到找到一个有点" feed = 1的线路。"

图形表示:

lines-points

1 个答案:

答案 0 :(得分:0)

MySQL版本8.0.1之前不支持递归查询。

这应该有效:

WITH RECURSIVE r(idLine, idStartPoint, idEndPoint) AS (
  SELECT idLine, idStartPoint, idEndPoint 
  FROM line WHERE idLine='YL19197'
  UNION ALL
  SELECT l.idLine, l.idStartPoint, l.idEndPoint
  FROM r JOIN line l ON l.idStartPoint = r.idEndPoint
  JOIN points p ON p.idPoint = r.idEndPoint 
  WHERE p.feed = 0
)
SELECT * FROM r;

使用您在问题中应该提供的数据输出:

+---------+--------------+------------+
| idLine  | idStartPoint | idEndPoint |
+---------+--------------+------------+
| YL19197 | YP004990     | YP004991   |
| YL19199 | YP004991     | YP004992   |
+---------+--------------+------------+

您的测试数据看起来没有足够的行来证明feed = 1时的终止。

如果您使用早于8.0.1的MySQL版本,则必须采用另一种方式。最直接的是编写应用程序代码来为一行执行一个查询,然后检查结果是否是您正在寻找的终端点,如果不是,则循环并对下一行进行另一个查询。