sql - 两点之间的路径
问题描述
我有一个两点之间的连接表:
RidgeId PointId1 PointId2
1 1 2
2 3 2
3 17 10
4 18 10
6 18 11
7 11 3
8 4 1
9 13 4
10 16 13
11 15 16
12 5 15
13 19 5
14 20 19
15 21 20
16 8 21
17 12 8
18 6 12
我想找到两点之间的路径。F。例如。
从 3 到 10
- 3、11
- 11、18
- 18, 10
如何编写查询以获得此结果?
编辑:
如何添加有关与原始行一致连接的信息,如下所示:
解决方案
您可以为此使用递归 CTE。由于您可以有多个路由,因此返回结果集的最简单方法是将其返回为 JSON
- 有两个锚点和两个递归,因为我们可以从 Point1 到 Point2 或每个节点的 vv
DECLARE @start int = 3;
DECLARE @end int = 10;
WITH cte AS (
SELECT
Point2 = p.PointId2,
p.RidgeId,
Json = (
SELECT p.RidgeId, p.PointId1, p.PointId2
FOR JSON PATH
)
FROM Points p
WHERE p.PointId1 = @start
UNION ALL
SELECT
Point2 = p.PointId1,
p.RidgeId,
Json = (
SELECT p.RidgeId, p.PointId1, p.PointId2
FOR JSON PATH
)
FROM Points p
WHERE p.PointId2 = @start
UNION ALL
SELECT
Point2 = p.PointId2,
p.RidgeId,
Json = JSON_MODIFY(cte.Json, 'append $', JSON_QUERY((
SELECT p.RidgeId, p.PointId1, p.PointId2
FOR JSON PATH, WITHOUT_ARRAY_WRAPPER
)))
FROM Points p
JOIN cte ON cte.Point2 = p.PointId1
WHERE p.RidgeId <> cte.RidgeId
UNION ALL
SELECT
Point2 = p.PointId1,
p.RidgeId,
Json = JSON_MODIFY(cte.Json, 'append $', JSON_QUERY((
SELECT p.RidgeId, p.PointId1, p.PointId2
FOR JSON PATH, WITHOUT_ARRAY_WRAPPER
)))
FROM Points p
JOIN cte ON cte.Point2 = p.PointId2
WHERE p.RidgeId <> cte.RidgeId
)
SELECT Json
FROM cte
WHERE cte.Point2 = @end;
结果 |
---|
[{"RidgeId":7,"PointId1":11,"PointId2":3}, {"RidgeId":6,"PointId1":18,"PointId2":11}, {"RidgeId":4,"PointId1 ":18,"PointId2":10}] |
这不能很好地处理节点中的循环。理想情况下,您应该通过在每个递归部分中分解 JSON 并检查我们不会返回自己来检查是否没有循环
推荐阅读
- c# - C#如何根据用户使用数据绑定选择的内容随机生成字符串
- html - 如何在屏幕尺寸更改期间将两个单独的居中单词保持在同一行?
- github - Does this .gitignore laravel makes sense when you're working with a team?
- python - 使用 opencv 在 OCR 期间识别变音字符
- node.js - Validator.js 在随机 gmail 地址上返回无效
- mysql - Laravel 哪里不存在
- json - Hive 复杂数据类型查询
- javascript - 如何在标头请求中添加参数?
- visual-studio - 未找到 premake 脚本(premake5.lua)错误
- vue.js - Vue Cli 3 和 Firebase 服务工作者注册