TSQL CTEとソートグラフ

common-table-expression hierarchical-data sql-server tsql

以下の構造とサンプルデータの表を使用します。

TableActivity -------------タイプVARCHAR(8)アクティビティVARCHAR(8)RelatedActivity VARCHAR(8)

タイプアクティビティ関連アクティビティ------------------------------------------スタートa  -  Transfer ab開始b  - 転送bc開始c  - 停止c  - 転送cb停止b  - 転送ba停止a  -

次のことを達成するためにCTEクエリを書くことは可能でしょうか。

GetActivities( 'a')

注文アクティビティ------------------- 0 a 1 b 2 c

再帰的な文で行を返すのを止めるようなものを書くのに苦労しています。

何か案は?

編集

GetActivities( ‘a’)を明確にします。 この関数は、 ‘a’の ‘Start’アクティビティを見つけ、 ‘a’上の ‘Transfer’アクティビティを見つけるように進みます。 その時点で、関数は ‘b’で再帰し、結果として ‘c’でサンプルデータを再帰することができます。 クエリは、 ‘転送’を介して ‘a’に関連するすべてのアクティビティを返す必要があります。 この活動のネスティングは必要に応じて深くすることができ、知られていません(したがって組合はありません)。 私が抱えている難しさは、別の ‘転送’が元に戻ることです。 ‘b’ – > ‘a’ 再帰クエリでこれがどのようにループを作成するかがわかります。

もう1つの明確化:アクティビティテーブルの転送はスタックとして振る舞います。 データがテーブルにどのように入力されるかは次のとおりです(C#)。

using(Activity.Start( "a")){//(Activity.Start( "b")を使用してカバーの下の 'b'に転送){//(Activity.Start( "cを使用してカバーの下の 'c'に転送")){} //カバーの下の 'b'に転送} // //カバーの下の 'a'に転送}

  0  0


ベストアンサー

Erwins入力に基づいて:

@TableActivityテーブルを宣言する([Type] VARCHAR(8)、Activity VARCHAR(8)、RelatedActivity VARCHAR(8))

挿入@TableActivity選択 '開始'、 'a'、 ' - '結合選択 '転送'、 'a'、 'b'結合選択 '開始'、 'b'、 ' - '結合選択 '転送'、 'b' 、 'c'共用体選択 '開始'、 'c'、 ' - '共用体選択 '転送'、 'c'、 'd'共用体選択 '転送'、 'c'、 'e'共用体選択 '開始'、 ' d '、'  -  'ユニオン選択'停止 '、' d '、'  -  'ユニオン選択'開始 '、' e '、'  -  'ユニオン選択'停止 '、' e '、'  -  'ユニオン選択'転送 ' 、 'd'、 'c'ユニオン選択 '転送'、 'e'、 'c'ユニオン選択 '停止'、 'c'、 ' - 'ユニオン選択 '転送'、 'c'、 'b'ユニオン選択停止 '、' b '、'  -  'ユニオン選択'転送 '、' b '、' a 'ユニオン選択'ストップ '、' a '、'  -  'ユニオン選択'スタート '、' 1 '、'  -  'ユニオン'転送'、 '1'、 '2'を選択します。 '開始'、 '2'、 ' - 'を選択します。 '転送'、 '2'、 '3'を選択します。 '開始'、 '3'、 ' - を選択します。 'union select' Transfer '、' 3 '、' 4 'union select' Start '、' 4 '、'  -  'union select' Stop '、' 4 '、'  -  'union select' Transfer '、' 4 '、 '3'ユニオン選択 '停止'、 '3'、 ' - 'ユニオン選択 '転送'、 '3'、 '2'ユニオン選択 '停止'、 '2'、 ' - 'ユニオン選択 '転送'、 '2 '、' 1 'ユニオンセレクト'停止'、 '1'、 ' - '

@activityを宣言するvarchar(8)set @activity = 'a'

; WITH ActivitiesGraph(activity、relatedactivity)AS(SELECTアクティビティ、relatedactivity FROM @TableActivity root WHERE root.activity = @activity AND root.type = '転送'

UNION ALL

SELECT next.activity、next.relatedactivityからFROM @TableActivity next INNER JOIN ActivitiesGraph previous ON next.activity = prior.relatedactivity WHERE next.type = '転送' AND prior.activity!= next.relatedactivity AND prior.activity!= next.activity )@TableActivityからのSELECTアクティビティWHERE activity = @activity

連合

SELECT関連のアクティビティからアクティビティグラフ

1


再帰クエリは本当に必要ですか? 提供したサンプルデータに基づいて、必要なことはアクティビティが停止した順序を逆に報告することです。

@TableActivityテーブルを宣言する([Type] VARCHAR(8)、Activity VARCHAR(8)、RelatedActivity VARCHAR(8))

挿入@TableActivity選択 '開始'、 'a'、 ' - '結合選択 '転送'、 'a'、 'b'結合選択 '開始'、 'b'、 ' - '結合選択 '転送'、 'b' 、 'c'共用体選択 '開始'、 'c'、 ' - '共用体選択 '停止'、 'c'、 ' - '共用体選択 '転送'、 'c'、 'b'共用体選択 '停止'、 ' b '、'  -  'ユニオン選択'転送 '、' b '、' a 'ユニオン選択'停止 '、' a '、'  -  '

アクティビティを選択、ROW_NUMBER()OVER(ORDER BYアクティビティ) -  1 @TableActivityから1 AS、ここで[Type] = 'Stop'で2

0


あなたはあなたの ‘getactivities()’のものの意図された意味についての詳細を与えることに失敗しました。

それで質問に答えるのは難しくなります。

しかし、とにかく、あなたが ‘再帰’について述べたので、私はあなたが結果セットに与えられた活動に関連した間接的なレベルのあらゆる活動を含むことを望むと思います。

「間接的なレベルで」という部分があるため、再帰を避けることはできません。 それは大体次のように動作するはずです。

与えられた一連の活動( ‘a’)から始めて関連する活動( ‘b’)を見つけます。 見つかった新しいアクティビティから、すでに見つかったアクティビティを削除します(なし)。 残りのものを結果セットに追加して、このセットで繰り返します。与えられたアクティビティのセット( ‘b’)で、関連するアクティビティ( ‘a’ ‘c’)を見つけます。 見つかった新しいアクティビティから、既に見つけたアクティビティ( ‘a’)を削除します。 残りのもの( ‘c’)を結果セットに追加し、このセットで繰り返します。与えられた一連のアクティビティー( ‘c’)で、関連するアクティビティー( ‘b’)を見つけます。 見つかった新しいアクティビティから、すでに見つけたアクティビティを削除します( ‘b’)。 結果セットに残りのもの(none)を追加すれば、何もないので完了です。

申し訳ありませんが、これをSQLに変換することはできません。

0


試してみましたが、それがいいのかどうかわかりません。 そうでない場合は無視してください。

WITH TMP AS (
SELECT activity, relatedactivity
FROM tableactivity root
WHERE root.activity = 'a' and root.type='transfer'
UNION ALL
SELECT next.activity, next.relatedactivity
FROM tableactivity next, TMP prior
WHERE prior.relatedactivity = next.activity and next.type='transfer'
  AND not exists (SELECT * FROM TMP ttmp
                   WHERE ttmp.activity = next.relatedactivity
                     AND ttmp.relatedactivity = next.activity)
                 )
)
SELECT relatedactivity FROM TMP
UNION (ALL ???)
SELECT 'a' from <nonemptytable>

PS

あなたの `orderednumber ‘に関しては、それはグラフとそのクロージャーにはあまり適合しない概念です。 aからcまでの長さが異なる複数の異なるパスがある場合、あなたはあなたの番号を何にしたいですか?

0


タイトルとURLをコピーしました