2012-04-12 11 views
1

件数でグループ化されたデータを扱っています。 count > 2の各レコードは個々のレコードに吹き飛ばす必要があり、そのレベルで別のデータセットと比較する必要があります。GROUP BYを逆転/吹き飛ばします

データは、この(。。それは、これは、顧客がそれを送ることができる唯一の方法である。この形式でスタックしている)のようになります。

OwnerNumber ItemCode ItemNumber CountOfItems 
1234 Item1 Item1-001 3 
1234 Item1 Item1-002 1 
1234 Item1 Item1-003 2 
1234 Item2 Item2-001 1 

そして、私はこのような形式のデータを必要とする(動的にするためにハードコーディングなしCountOfItemsの値):

OwnerNumber ItemCode ItemNumber 
1234 Item1 Item1-001 
1234 Item1 Item1-001 
1234 Item1 Item1-001 
1234 Item1 Item1-002 
1234 Item1 Item1-003 
1234 Item1 Item1-003 
1234 Item2 Item2-001 

私はこれを行うにはきれいな方法(または任意の方法のまわりで私の頭をラップすることはできませんいくつかの理由)。

答えて

4

あなたが共通テーブル式

WITH CTE AS (
    SELECT OwnerNumber,ItemCode,ItemNumber,CountOfItems FROM table 

    UNION ALL SELECT OwnerNumber,ItemCode,ItemNumber,CountOfItems-1 
    FROM CTE 
    WHERE CountOfItems >= 2 
) 
SELECT OwnerNumber,ItemCode,ItemNumber 
FROM CTE 
ORDER BY ItemNumber 
OPTION (MAXRECURSION 0); 

を編集して管理することができます。

追加MAXRECURSION CountOfItemsがDev_etterによって指摘されたデフォルトの最大再帰を超える状況を処理する

+0

ありがとうございます。いくつかの小さなニットピッキング:特に、テーブルの順序が変更される可能性がある場合は、常にどの列がSELECTされているかを指定するのが最善です。同じ理由がCTE列の定義にも当てはまります。 –

+0

真実です、私は同意します。私はそれを編集した。しかし、なぜCTEの定義列について気にしていますか?それらは 'SELECT'節で私が選択した順序から間接的に定義されますか? – ANisus

+0

パーフェクト!ありがとうございました!私は再帰的なCTEについて読むことを覚えていますが、まだ使用していません。私はちょうど1つを使用する適切な時がどのようにわからなかったと思います。 –

3

うーん....私は、このための再帰CTEを好きだと思う:

WITH Data (OwnerNumber, ItemCode, ItemNumber, CountOfItems) as (
      SELECT OwnerNumber, ItemCode, ItemNumber, CountOfItems 
      FROM OriginalTable 
      UNION ALL 
      SELECT OwnerNumber, ItemCode, ItemNumber, CountOfItems - 1 
      FROM Data 
      WHERE CountOfItems > 1) 
SELECT OwnerNumber, ItemCode, ItemNumber 
FROM Data 
ORDER BY OwnerNumber, ItemCode, ItemNumber 
+0

私はあなたが考えている方法が好きです。ほぼ同じ! – ANisus

+0

私はANISUSへの答えは、彼が1分であなたを倒したからだ。両方とも同じアプローチで、正しい結果を得ることができます。ありがとう! –

3

以下のクエリで再帰を避けることができ、より効率的になると思います。ここで、テーブルNは、少なくともCountOfItemsの最大値と同じ数の行を持つテーブルです。

これは、ORDER BYのないTOPが悪い考えではないクエリのまれな例です。

select 
    OwnerNumber, 
    ItemCode, 
    ItemNumber 
from t 
cross apply (
    select top (CountOfItems) null 
    from N 
) as N(c) 
+0

+1楽しく創造的なソリューションです。私はダミーのテーブルで遊んで、トップのための可変の値を使用するような方法を見たことがない。しかし、それがより効率的であるかどうか私は自分自身を考えていない。 – ANisus

+0

異なるアプローチをお寄せいただきありがとうございます。私はこれをテストしましたが、4分30秒で結果の約半分しか吹き飛ばされませんでした。他のクエリは4分強で完了します。 FYI私は、600万を超えるグループ化されたレコードを扱っており、400万を超えるレコードを吹き飛ばしています。 –

関連する問題