我得到了一些帮助,使用以下声明找到前10个分数,包括绑定条目
select T.EntryID, T.CategoryID, T.Score
from (
select EntryID, CategoryID, Score,
dense_rank() over(order by Score) as rn
from YourTable
) T
where T.rn <= 10
Run Code Online (Sandbox Code Playgroud)
(感谢[mikael-eriksson]:https://stackoverflow.com/users/569436/mikael-eriksson )
[问题]:MSSQL选择前10名但包含重复值的列这里是示例数据:
EntryID CategoryID Score
3036 1 85
3159 1 85
3039 1 84
3146 1 83
3225 1 82
3045 1 82
3047 1 80
3048 1 80
3049 1 80
3193 1 80
3098 1 80
3025 1 72
3082 1 70
3167 1 70
3122 1 67
3220 1 65
3080 1 65
3168 1 64
______________________
Total Entries >= 18
Run Code Online (Sandbox Code Playgroud)
要求前10名中的每个类别至少有一个条目(或者不论它是什么,即前100名),在这种情况下有3个类别.
现在我需要做的就是在前10名中每个类别至少包含一个条目.即如果所有前10个分数都来自第1类,并且有3个类别,我需要从第1类中删除2个最低分数,包括第2类和第3类的最高得分条目.
从结果中可以看出,所有条目都来自类别1,因此我需要从结果集中删除EntryID的3220,3080和3168,因为它们是得分最低的,并且包括类别2中得分最高的条目以及最高得分条目在类别3中评分条目,以便结果看起来像这样:
EntryID CategoryID Score
3036 1 85
3159 1 85
3039 1 84
3146 1 83
3225 1 82
3045 1 82
3047 1 80
3048 1 80
3049 1 80
3193 1 80
3098 1 80
3025 1 72
3082 1 70
3167 1 70
3122 1 67
3019 3 60
3800 2 54
______________________
Total Entries >= 17
Run Code Online (Sandbox Code Playgroud)
同样的情况也适用于以下情况,让我们看看前5个而不是前10个,以使它更容易在眼睛上看,正如您在本例中所见,前5个分数排除了类别2中的条目
EntryID CategoryID Score
3036 1 85
3159 1 85
3039 1 84
3146 1 83
3225 1 82
3045 1 82
3019 3 60
______________________
Total Entries >= 7
Run Code Online (Sandbox Code Playgroud)
在这种情况下,条目3225和3045需要删除,因为它们是得分最低的条目(需要包括3047,即使它是得分最低的条目我需要结果中所有类别的条目)并且我需要包括最高得分从类别2进入,我希望这样的事情:
EntryID CategoryID Score
3036 1 85
3159 1 85
3039 1 84
3146 1 83
3019 3 60
3800 2 54
______________________
Total Entries >= 6
Run Code Online (Sandbox Code Playgroud)
然后可能存在可能没有进入特定类别的情况,例如没有类别2条目,因此结果应该仍然具有与前5个的原始结果集一样的前5个(包括在下面)作为参考)
EntryID CategoryID Score
3036 1 85
3159 1 85
3039 1 84
3146 1 83
3225 1 82
3045 1 82
3019 3 60
______________________
Total Entries >= 7
Run Code Online (Sandbox Code Playgroud)
如果我重复自己,请原谅,我只是想清楚地理解;)
我真的感谢你的帮助!
正如我所看到的,您需要以更复杂的方式对行进行排名,以便包括每个类别中最重要的条目,无论它们的值如何,并且根据它们的整体包含不是顶级条目的条目排名.
我要提出的建议可能不是最有效的解决方案,但它应该有效,如果没有别的办法,可能会激励其他人提出更好的建议:
WITH ranked1 AS (
SELECT
*,
RankByCategory = DENSE_RANK() OVER (
PARTITION BY CategoryID
ORDER BY Score DESC
)
FROM YourTable
),
ranked2 AS (
SELECT
*,
FinalRank = DENSE_RANK() OVER (
ORDER BY
CASE RankByCategory WHEN 1 THEN 1 ELSE 2 END,
Score DESC
)
FROM ranked1
)
SELECT
EntryID,
CategoryID,
Score
FROM ranked2
WHERE FinalRank <= @top_n
;
Run Code Online (Sandbox Code Playgroud)
第一个CTE按类别对行进行排名,从而让我们找出哪些条目成为各自类别中的最高条目.下一步(第二次CTE)是关于获得全球排名,这次考虑一个条目是否是其类别中的最高级别.类别最高值获得较低排名,因此确保包含在最终结果中.(当然,您需要确保类别数不大于您希望在输出中接收的不同值的数量.)
这是SQL Fiddle的一个实例.
| 归档时间: |
|
| 查看次数: |
712 次 |
| 最近记录: |