よくわからない問題に取り組んできました。クロス結合、CTE、ウィンドウ関数などのさまざまな組み合わせを試しましたが、うまくいきませんでした。また、動的SQLルートを使用したくありません。誰か助けてもらえますか?
グループ化された値の変数セットが与えられると、すべての可能な組み合わせが垂直方向に生成されます(派生グループ、値)
追加情報:
- 2つの組み合わせは、順序に関係なく、同じ値のセットを持つべきではありません。例:すでに(1,2)がある場合は、(2,1)を生成しないでください。(1,2,3)の場合は、(1,3,2)、(2,1,3)、(2 、3,1)、(3,1,2)、(3,2,1)
- 同じグループの値を組み合わせてはいけません
- グループに関係なく、すべての値は一意です。最初のグループ化の唯一の理由は、ルール#2を適用することです。
例:開始グループとの値が与えられた
InputGroup値
- 1 8
- 2 7
- 2 9
- 3 1
- 3 6
- 3 3
この出力を生成します
OutputGroup値
- 1 8
- 2 7
- 3 9
- 4 1
- 5 6
- 6 3
- 7 8
- 7 7
- 8 8
- 8 9
- 9 8
- 9 1
- 10 8
- 10 6
- 11 8
- 11 3
- 12 7
- 121
- 13 7
- 13 6
- 14 7
- 14 3
- 15 9
- 151
- 16 9
- 16 6
- 17 9
- 17 3
- 18 8
- 18 7
- 18 1
- 19 8
- 19 7
- 19 6
- 20 8
- 20 7
- 20 3
- 21 8
- 21 9
- 21 1
- 22 8
- 22 9
- 22 6
- 23 8
- 23 9
- 23 3
これが、出力を生成するための手動の非垂直方式です。
CREATE TABLE #temp1 (GroupID INT, MyValue INT)
INSERT INTO #temp1 (GroupID, MyValue)
VALUES (1,8),(2,7),(2,9),(3,1),(3,6),(3,3)
--1st set of possibilities
SELECT MyValue
FROM #temp1
--2nd set of possibilities
SELECT a.MyValue, b.MyValue
FROM #temp1 a
JOIN #temp1 b
ON a.GroupID < b.GroupID
--3rd set
SELECT a.MyValue, b.MyValue, c.MyValue
FROM #temp1 a
JOIN #temp1 b
ON a.GroupID < b.GroupID
JOIN #temp1 c
ON b.GroupID < c.GroupID
DROP TABLE #temp1
私の問題は、開始値の数が可変である可能性があることです。これを念頭に置いて、出力はグループ化された垂直セットである必要があるため、2列のみを返します。1は、番号と番号自体をグループ化します。この特定の例では、上記のように23の異なるグループを持つ46の行が必要です。
私は変更を続け、最終的に廃棄したCTEを作成しました。
WITH MyCTE
AS (SELECT 1 AS Level, DENSE_RANK() OVER (ORDER BY GroupID, MyValue) AS DgroupID, GroupID, MyValue
FROM #temp1
UNION ALL
SELECT a.Level + 1, DENSE_RANK() OVER (ORDER BY b.GroupID, b.MyValue), b.GroupID, b.MyValue
FROM MyCTE a
JOIN #temp1 b
ON a.GroupID < b.GroupID)
SELECT DENSE_RANK() OVER (ORDER BY Level, DgroupID), MyValue
FROM MyCTE
これに関する明らかな問題:
1)各行に増分値を与えるために使用したウィンドウ関数が期待どおりに機能しませんでした。これはおそらく、CTEの動作方法が原因です。パフォーマンスには良いが、私には悪い。ROW_NUMBERウィンドウ関数は同じことを行います。私がやろうとしているのは、各反復内で行を自動インクリメントして、テーブルが「ピボット解除」されたときにグループを識別できるようにすることだけです。CTEが非常に高速である理由は、実際にはセットベースの操作であるため、再帰があったとしても、意図した結果を生成するためにループ/反復モードの考え方に頼ることができないためだと思います。私のすべての仮定で私を修正してください
2)ピボットを解除します。行のセットを取得し、列を行にピボット解除する必要があります。各行は元の行の識別子を保持して、グループ化されていることを示します。SQL Serverには、UNPIVOTと呼ばれるすばらしいコマンドがあります。これは、設計時にピボットを解除する列の数を知る必要があるため、まったく役に立ちません。これの要点は、可変数の入力を提供し、予測可能な出力を生成できるようにすることです。