2012-04-11 108 views
1

我有一种情况,我需要根据表中的设置和序号集仅显示最上面的行。根据序数和属性数据选择前n条记录

下面的示例数据集显示了两个客户;每个客户都有不同的产品。 由于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是1对CustomerID,1和2对CustomerID,5我会看到类似。

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

如何才能做到这一点?

包括实际结果集的屏幕截图,其中突出显示了我想要筛选的内容,但可能会对您有所帮助。

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

+1

如果什么客户的行有三个不同的'NumRowsToShow'(比如1,2,3 )? – 2012-04-11 18:56:30

+0

那不会发生; NumRowsToShow来自每个CustomerID的设置。一样的。这是几个查询的结果。客户/产品ID不是实际的结果集,我只是试图提供一个简单的例子,我试图过滤掉。 – sugarcrum 2012-04-11 19:23:59

回答

6

感觉就像 “作弊在考试中”:

SELECT CustomerID, ProductID 
FROM tableX 
WHERE Ordinal <= NumRowsToShow 

如果作为意见建议,在Ordinal可以有10, 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 | 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    | 
+0

该表是另一个查询的结果;这只是作为我尝试过滤的结果数据集的一个简单示例。我喜欢Ordinal <= NumRowsToShow的简单方法。它几乎可行,除了“序数”可能是10,20,30 ..不一定是1,2,3。 – sugarcrum 2012-04-11 19:22:32

+0

非常感谢您花时间回复。分区声明正是我所期待的。我正在走这条路,但无法找到构建它的正确方法。非常非常感谢您的帮助。 – sugarcrum 2012-04-11 19:40:37