2012-04-11 5 views
1

テーブルの設定と序数セットに基づいて上の行のみを表示する必要がある場合があります。序数と属性データに基づいて上位n個のレコードを選択する

以下のデータセット例は、2人の顧客を示しています。顧客のそれぞれは異なる製品を持っています。 NumRowsToShowは「1」なので、私は顧客ごとに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    | 

クエリが実行された後、結果セットはNumRowsToShowが得意5のために得意先1のための1と2だった場合、私のようなものを見るのと同じシナリオで

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

でなければなりません。クエリが実行された後、結果セットが

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

どのようにこれを行うことができますか?あるべき

| 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    | 

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

Screencap http://www.harpernet.net/se/cap01.jpg

+1

し、顧客の行は1,2,3を言う(3異なる 'NumRowsToShow'を持っていたものならば)? –

+0

それは起こりません。 NumRowsToShowは、CustomerIDごとに設定されています。それは同じだ。これは、いくつかのクエリの結果です。 Customer/ProductIDは実際の結果セットではありません。フィルタリングしようとしているものの簡単な例を提供しようとしています。 – sugarcrum

答えて

6

それは "試験で不正行為" のように感じている:

SELECT CustomerID, ProductID 
FROM tableX 
WHERE Ordinal <= NumRowsToShow 

コメントが示唆するように、Ordinal10, 20, 30値と1, ..., 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 | 
+------------+-----------+---------+ 
| 1   |A   |1  | 
| 1   |B   |2  | 
| 1   |C   |3  | 
| 5   |D   |1  | 
| 5   |E   |2  | 
| 5   |F   |3  | 

と::

| 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 | NumRowsToShow | 
+------------+---------------+ 
| 1   |1    | 
| 5   |2    | 
+0

テーブルは別のクエリの結果です。これは、フィルタリングしようとしている結果のデータセットの簡単な例として使用されています。 Ordinal <= NumRowsToShowの単純なアプローチが好きです。それはほとんど正常に動作しますが、 "序数"は10,20,30 ... 1,2,3 ...である必要はありません。 – sugarcrum

+0

応答に時間を割いてくれてありがとう。 Partitionステートメントはまさに私が探していたものです。私はこの道を歩いていたが、それを構造化する正しい方法を見つけることができなかった。非常に、非常に多くの助けを感謝します。 – sugarcrum

関連する問題