sql - 如何在 SQL Server 中重写此查询 (PostgreSQL)?

标签 sql sql-server postgresql common-table-expression recursive-query

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

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

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 编写递归查询。进行了搜索和检查 this page但仍然没有运气。我无法运行查询。

最佳答案

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

我设法将有问题的查询转换为 SQL;

  1. 将整数值转换为 varchar(MAX)。如果您没有将 varchar 的长度指定为 MAX,您将得到“Types don't match between anchor and the recursive part in column...”

  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;

关于sql - 如何在 SQL Server 中重写此查询 (PostgreSQL)?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/5833646/

相关文章:

sql - 选择 parent 以获取 parent 子女中有趣的属性列表

JQuery 数据表分页,仅显示每页的结果

mysql - 有什么办法可以提交部分事务吗?

sql - 通过分区聚合相邻行

sql - 形成查询以查找重复的邮政编码

.net - PostgreSQL 相当于 SQL Server 的 TVP

sql - 网络适​​配器无法在 SQL 开发人员中建立连接

sql - Oracle SQL 将字符串转换为数字,异常(exception)情况是将文本视为 0

sql - 添加 number + varchar 以获得字符串连接

sql - 数据类型限定符定义 PostgreSQL