2011-05-13 22 views
3

これは宿題の質問から来たものです。私たちはSQLクエリを動的に構築することでそれを解決しました。しかし、純粋なSQLを使用することができるのであれば、私たちは興味があります。特定の深さのすべてのリンクを見つける

目的の簡略化: ソースIDと宛先IDの2つの列を持つ表があります。 idとnを指定すると、与えられたidから距離のすべてのidがより小さい等しい nを見つける必要があります。

明確化の編集:
ウェブリンクを表すものとして、テーブルを考えてみて。行(1,3)が表に表示されている場合は、Webページ1にWebページ3へのリンクがあることを意味します。
開始Webページから到達可能なすべてのWebページをn回クリックするか、もっと少なく。

"好奇心"の質問ですので、好きなSQL実装を使用してください。 "純粋なSQL"は、 "構造化されたクエリスタイル"に適合するすべてのものを意味します。ループを使用することは、「純粋なSQL」とはみなされません(質問のため)。

+3

あなたの質問はあまり明確ではありません。与えられたIDから距離nのすべてのIDであなたはどういう意味ですか?あなたのテーブルは何らかの木を表していますか?サンプルデータに「N-deep」が何を意味するのかを明確に示すような表の例を挙げることはできますか? –

+0

...純粋なSQLはどういう意味ですか? –

+1

...あなたはどのdbmsを使用していますか? –

答えて

1

あなたはので、任意のNのための一般的な解決策は、ない可能で、リレーショナル代数や純粋な古いSQLを使用してtransitive closureを表現することはできません。

あなたができることは、動的に生成されたクエリのアプローチと同じように、「コンパイル時」にNを選択し、たくさんの結合を使用することです。

1

簡単な答えは、「n」の場合、バニラSQLでは不可能かもしれないということです。あなたがしようとしているのは、与えられた深さ "n"までの幅広いリンクをすべて調べることです。 MS SQLで

1

は2005+あなたが

;WITH RecursiveTbl AS 
(
    SELECT WL.SouriceID, WL.DestinationId, 0 AS level 
    FROM WEBLINKS WL 
    WHERE WL.SouriceID = @your_top_level_id 

    UNION ALL 

    SELECT WL.SouriceID, WL.DestinationId, RWL.level + 1 AS level 
    FROM RecursiveTbl RWL 
    JOIN WEBLINKS WL ON RWL.DestinationId = WL.SourceID 
) 
SELECT * FROM RecursiveTbl WHERE level BETWEEN 1 AND 3; 

再帰クエリを使用することができ、クエリは、最初は同じソースIDを持つレコードを選択し、再帰的に自分自身に参加します。

その後、必要のないすべてのレコードをフィルタリングするのと同じくらい簡単です。

関連する問題