1

数日前、私は1、2、3度の接続について質問しました。質問リンクと@Snoopyは、私のすべての問題を解決できる記事リンクを提供しました。記事リンク

この記事を注意深く調べましたが、SQLServerでWithRecursiveクエリを使用できませんでした。

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を使用してSQLServerで再帰クエリを作成する方法がわかりません。検索してこのページを調べましたが、それでも運がありません。クエリを実行できませんでした。

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

再帰CTEはSQLServerでも同じである必要があります(少なくとも最近のバージョンでは、これは間違いがなければSQL Server 2005で導入されました)recursive。キーワードは省略してください。

||SQL ServerはSQL標準に準拠していないため、連結を次のように置き換える必要があることに注意してください。+

于 2011-04-29T16:56:11.947 に答える