sug*_*rum 1 t-sql sql-server sql-server-2008
我有一个案例,我需要根据表中的设置和序数集只显示顶行.
下面的示例数据集显示了两个客户; 每个客户都有不同的产品.因为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 |
Run Code Online (Sandbox Code Playgroud)
运行查询后的结果集应该是
| CustomerID | ProductID |
+------------+-----------+
| 1 |A |
| 5 |D |
Run Code Online (Sandbox Code Playgroud)
在同一场景中,如果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 |
Run Code Online (Sandbox Code Playgroud)
运行查询后的结果集应该是
| CustomerID | ProductID |
+------------+-----------+
| 1 |A |
| 5 |D |
| 5 |E |
Run Code Online (Sandbox Code Playgroud)
如何才能做到这一点?
包括实际结果集的屏幕上限,以及我正在尝试过滤的内容的亮点可能有点帮助.
感觉就像"在考试中作弊":
SELECT CustomerID, ProductID
FROM tableX
WHERE Ordinal <= NumRowsToShow
Run Code Online (Sandbox Code Playgroud)
如果,如评论所示,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
Run Code Online (Sandbox Code Playgroud)
甚至更好,:
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 ;
Run Code Online (Sandbox Code Playgroud)
测试: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 |
Run Code Online (Sandbox Code Playgroud)
可以归一化为2个表格:
| CustomerID | ProductID | Ordinal |
+------------+-----------+---------+
| 1 |A |1 |
| 1 |B |2 |
| 1 |C |3 |
| 5 |D |1 |
| 5 |E |2 |
| 5 |F |3 |
Run Code Online (Sandbox Code Playgroud)
和:
| CustomerID | NumRowsToShow |
+------------+---------------+
| 1 |1 |
| 5 |2 |
Run Code Online (Sandbox Code Playgroud)