1

テーブルの設定と序数のセットに基づいて、一番上の行だけを表示する必要がある場合があります。

以下のデータセットの例は、2人の顧客を示しています。顧客ごとに異なる製品があります。は「1」なのでNumRowsToShow、各顧客に対して1行(序数に基づく一番上の行)のみを表示したいと思います。

| CustomerID | ProductID | Ordinal | NumRowsToShow |
+------------+-----------+---------+---------------+
| 1          |A          |1        |1              |
| 1          |B          |2        |1              |
| 1          |C          |3        |1              |
| 5          |D          |1        |1              |
| 5          |E          |2        |1              |
| 5          |F          |3        |1              |

クエリの実行後の結果セットは次のようになります。

| CustomerID | ProductID |
+------------+-----------+
| 1          |A          |
| 5          |D          |

同じシナリオNumRowsToShowで、customerID 1が1、CustomerID 5が2の場合、次のようになります。

| CustomerID | ProductID | Ordinal | NumRowsToShow |
+------------+-----------+---------+---------------+
| 1          |A          |1        |1              |
| 1          |B          |2        |1              |
| 1          |C          |3        |1              |
| 5          |D          |1        |2              |
| 5          |E          |2        |2              |
| 5          |F          |3        |2              |

クエリの実行後の結果セットは次のようになります。

| CustomerID | ProductID |
+------------+-----------+
| 1          |A          |
| 5          |D          |
| 5          |E          |

これはどのように行うことができますか?

私がフィルタリングしようとしているもののハイライトを含む実際の結果セットのスクリーンキャップを含めると、少し役立つかもしれません。

スクリーンショット
(出典:harpernet.net

4

1 に答える 1

6

「試験でカンニング」のように感じます。

SELECT CustomerID, ProductID
FROM tableX
WHERE Ordinal <= NumRowsToShow

コメントが示唆するように、値だけでなく値Ordinalを持つことができる場合、これは機能します。10, 20, 301, ..., n

SELECT t.CustomerID, t.ProductID
FROM tableX AS t
  JOIN tableX AS tt
    ON  tt.CustomerID = t.CustomerID
    AND tt.Ordinal <= t.Ordinal
GROUP BY t.CustomerID
       , t.ProductID
       , t.NumRowsToShow
HAVING COUNT(*) <= t.NumRowsToShow

またはさらに良いことに、

SELECT CustomerID, ProductID
FROM
  ( SELECT CustomerID, ProductID, NumRowsToShow
         , ROW_NUMBER() OVER( PARTITION BY CustomerID 
                              ORDER BY Ordinal
                            ) AS Rn
    FROM tableX
  ) AS tmp
WHERE Rn <= NumRowsToShow ;

テスト: SQL-Fiddle


あなたのテーブルは正規化されていないようです。NumRowsToShow列に重複した情報が含まれているため、更新の異常が発生する可能性があります。これ:

| CustomerID | ProductID | Ordinal | NumRowsToShow |
+------------+-----------+---------+---------------+
| 1          |A          |1        |1              |
| 1          |B          |2        |1              |
| 1          |C          |3        |1              |
| 5          |D          |1        |2              |
| 5          |E          |2        |2              |
| 5          |F          |3        |2              |

2 つのテーブルに正規化できます。

| CustomerID | ProductID | Ordinal |
+------------+-----------+---------+
| 1          |A          |1        |
| 1          |B          |2        |
| 1          |C          |3        |
| 5          |D          |1        |
| 5          |E          |2        |
| 5          |F          |3        |

と:

| CustomerID | NumRowsToShow |
+------------+---------------+
| 1          |1              |
| 5          |2              |
于 2012-04-11T18:58:18.173 に答える