1

几天前,我问了一个关于 1,2 和 3. 度连接的问题。Question Link和@Snoopy 提供了一个可以解决我所有问题的文章链接。文章链接

我仔细检查了这篇文章,但我无法在 SQL Server 中使用 With Recursive query。

PostgreSQL 查询:

SELECT a AS you,
   b AS mightknow,
   shared_connection,
   CASE
     WHEN (n1.feat1 = n2.feat1 AND n1.feat1 = n3.feat1) THEN 'feat1 in common'
     WHEN (n1.feat2 = n2.feat2 AND n1.feat2 = n3.feat2) THEN 'feat2 in common'
     ELSE 'nothing in common'
   END AS reason
 FROM (
 WITH RECURSIVE transitive_closure(a, b, distance, path_string) AS
 ( SELECT a, b, 1 AS distance,
     a || '.' || b || '.' AS path_string,
     b AS direct_connection
FROM edges2
 WHERE a = 1 -- set the starting node

 UNION ALL

 SELECT tc.a, e.b, tc.distance + 1,
     tc.path_string || e.b || '.' AS path_string,
     tc.direct_connection
FROM edges2 AS e
JOIN transitive_closure AS tc ON e.a = tc.b
 WHERE tc.path_string NOT LIKE '%' || e.b || '.%'
 AND tc.distance < 2
 )
 SELECT a,
   b,
   direct_connection AS shared_connection
 FROM transitive_closure
 WHERE distance = 2
 ) AS youmightknow
 LEFT JOIN nodes AS n1 ON youmightknow.a = n1.id
 LEFT JOIN nodes AS n2 ON youmightknow.b = n2.id
 LEFT JOIN nodes AS n3 ON youmightknow.shared_connection = n3.id
 WHERE (n1.feat1 = n2.feat1 AND n1.feat1 = n3.feat1)
 OR (n1.feat2 = n2.feat2 AND n1.feat2 = n3.feat2);

要不就

WITH RECURSIVE transitive_closure(a, b, distance, path_string) AS
( SELECT a, b, 1 AS distance,
     a || '.' || b || '.' AS path_string
FROM edges
WHERE a = 1 -- source

UNION ALL

SELECT tc.a, e.b, tc.distance + 1,
     tc.path_string || e.b || '.' AS path_string
FROM edges AS e
JOIN transitive_closure AS tc ON e.a = tc.b
WHERE tc.path_string NOT LIKE '%' || e.b || '.%'
)
SELECT * FROM transitive_closure
WHERE b=6 -- destination
ORDER BY a, b, distance;

正如我所说,我不知道如何使用 CTE 使用 SQL Server 编写递归查询。进行了搜索并检查了此页面,但仍然没有运气。我无法运行查询。

4

2 回答 2

4

如果有人感兴趣,这是答案;

我设法通过以下方式将相关查询转换为 SQL;

  1. 将整数值转换为 varchar(MAX)。如果您没有将 varchar 的长度指定为 MAX,您将得到“锚点和列中的递归部分之间的类型不匹配...”

  2. 我换了|| 到 +

  3. 我补充说;到查询的开头

  4. 最后,正如@a_horse_with_no_name 建议的那样,我从查询中删除了 RECURSIVE 。

结果;

;WITH transitive_closure(a, b, distance, path_string) AS
( SELECT a, b, 1 AS distance,
 CAST(a as varchar(MAX)) + '.' + CAST(b as varchar(MAX)) + '.' AS path_string
FROM edges
WHERE a = 1 -- source

UNION ALL

SELECT tc.a, e.b, tc.distance + 1, 
CAST(tc.path_string as varchar(MAX)) + CAST(e.b as varchar(MAX)) + '.' AS path_string
FROM edges AS e
JOIN transitive_closure AS tc ON e.a = tc.b
WHERE tc.path_string NOT LIKE '%' + CAST(e.b as varchar(MAX)) + '.%'
)
SELECT * FROM transitive_closure
WHERE b=6 -- destination
ORDER BY a, b, distance;
于 2011-05-01T12:31:13.043 回答
2

SQL Server 上的递归 CTE 应该是相同的(至少在最近的版本中,如果我没记错的话,这是在 SQL Server 2005 中引入的),只需省略recursive关键字即可。

请注意,SQL Server 不符合 SQL 标准,因此您需要将||连接替换为+

于 2011-04-29T16:56:11.947 回答