2

我有三个表 t1、t2 和 t3。t1 有我的第一点

--------------------------
| t1
--------------------------
| objectId, x, y     <--(these are fields)
--------------------------
| 30536, 1364690.09169,16518759.7879
|
--------------------------

t2 有我的几条折线,它们是它们的端点

--------------------------
| t2
--------------------------
| objectId, from_x, from_y, to_x, to_y     <--(these are fields)
--------------------------
| 43664, 1364815.8770, 16518764.8200, 1364806.6780, 16518760.9000
| 43665, 1364806.6780, 16518760.9000, 1364710.2130, 16518719.7700
| 43666, 1364710.2130, 16518719.7700, 1364709.4300, 16518720.3000
| 43667, 1364709.4300, 16518720.3000, 1364690.0920, 16518759.7900
| 43370, 1364843.6870, 16518667.7600, 1364815.8770, 16518764.8200
|-------------------------

t3 有我整条线的最终终点

--------------------------
| t3
--------------------------
| objectId, x, y     <--(these are fields)
--------------------------
| 11191, 1364843.68657, 16518667.7589
|
--------------------------

我确实四舍五入到小数点后两位,所以端点在某一点或另一点匹配。我需要做的是创建某种类型的递归查询来完成从开始到所有连接折线到最终端点的线。现在一些折线并不总是从 -> 到它可能是相反的方式到 -> 从这样一种组合。在这个例子中

这条线(30536 -> 43667 -> 43666 -> 43665 -> 43664 -> 43370 -> 11191)到达我的最终目的地。所以我只需要结果中的起点(30536)和终点(11191)。

4

1 回答 1

2

不容易,但我可以举个例子。

这是一个SQLFiddle,它具有像您这样的基本表结构和CTE解决方案。基本实现你需要的递归查询CTE。但这有点困难,因为你有 3 个不同的表。如果您可以在一个表中定义所有点并且可以为起点和终点添加一个不存在的值,那么如果不是这样,它会容易得多。(甚至为 NULL)。

表结构:

CREATE TABLE startpoint(
  id int,
  x int,
  y int
)

CREATE TABLE points(
  id int,
  fx int,
  fy int,
  tx int,
  ty int
)


CREATE TABLE endpoint(
  id int,
  x int,
  y int
)

INSERT INTO startpoint VALUES(1, 1,1)
INSERT INTO startpoint VALUES(6, 2,4)
INSERT INTO points VALUES (2, 1,1 , 2,1)
INSERT INTO points VALUES (3, 2,1 , 2,2)
INSERT INTO points VALUES (4, 2,4 , 2,5)
INSERT INTO points VALUES (7, 2,5 , 3,2)
INSERT INTO points VALUES (8, 3,2 , 3,3)
INSERT INTO points VALUES (9, 3,3 , 3,4)
INSERT INTO endpoint VALUES(5, 2,2)
INSERT INTO endpoint VALUES(10, 3,4)

询问:

WITH CTE_Points
AS
(
   SELECT
  -1 AS FromID,
  s.ID AS ToID,
  -1 AS fx,
  -1 AS fy,
  s.x as tx,
  s.y as ty
  FROM startpoint s
  WHERE s.ID = 6

  UNION ALL

  SELECT 
  cte1.ToID AS FromID,
  points.ID AS ToID,
  points.fx,
  points.fy,
  points.tx,
  points.ty
  FROM points
  INNER JOIN  CTE_Points cte1 ON (points.fx = cte1.tx AND points.fy = cte1.ty)
  OR (points.tx = cte1.fx AND points.ty = cte1.fy)
  WHERE points.ID != cte1.ToID AND points.ID != cte1.FromID 

  UNION ALL

  SELECT
  e.ID AS FromID,
  -1 AS ToID,
  -1 AS fx,
  -1 AS fy,
  -1 AS tx,
  -1 AS ty
  FROM CTE_Points
  INNER JOIN endpoint e ON (CTE_Points.fx = e.x AND CTE_Points.fy = e.y)
  OR (CTE_Points.tx = e.x AND CTE_Points.ty = e.y)
  OR (points.fx = cte1.fx AND points.fy = cte1.fy)
  OR (points.tx = cte1.tx AND points.ty = cte1.ty)
  WHERE e.ID != CTE_Points.ToID AND e.ID != CTE_Points.FromID 

  )
SELECT FromID AS ID FROM CTE_Points
WHERE FromID != -1
UNION
SELECT ToID AS ID FROM CTE_Points
WHERE  ToID != -1

您可以尝试将 s.ID 从 6 更改为 1,如何分别选择两个“方式”。

注意:这仅在您的表中没有连接时才有效,例如:Record1.FromX = Record2.FromX AND Record1.FromY = Record2.FromY)

于 2012-09-12T14:36:00.290 回答