我想制作一个我可以在视图中使用的线性分数公式。我在制作逻辑时遇到了麻烦。
数据:
*UserID (int)| *WidgetID (int)| Rank (int) | IsPreferred (bit)
1 | 1 | 1 | 1
1 | 2 | 2 | 1
1 | 3 | 3 | 1
1 | 4 | 1 | 0
1 | 5 | 2 | 0
2 | 1 | 1 | 1
用户#1最喜欢Widget#1,最讨厌Widget#4。用户#2只喜欢Widget#1(最多)。
我希望我的观点看起来像这样:
*UserID (int)| *WidgetID (int)| Rank (int) | IsPreferred (bit) | Score (int)
1 | 1 | 1 | 1 | 3
1 | 2 | 2 | 1 | 2
1 | 3 | 3 | 1 | 1
1 | 4 | 1 | 0 | -2
1 | 5 | 2 | 0 | -1
2 | 1 | 1 | 1 | 1
等级总是(现在)的绝对值在1-5(含)之间。 UserID和WidgetID都是主键,应用程序强制连续的唯一排名,所以我不必担心分数冲突。我想做这样的事情:
Select *, Case When IsPreferred = 1 Then (5 / Rank) Else -(5 / Rank) End As Score...
但这是指数性的,如果我们将来允许超过5个排名可能会导致问题......
我希望我不必在我的申请中这样做,因为那不是l33t
。我想PARTITION
或RANK
可以帮助我,但我还没有成功。
有人有任何想法吗?感谢
更新,请参阅我的回答below
答案 0 :(得分:0)
你真的需要在SQL中这样做吗?我认为这种公式,因为它是复杂的业务逻辑,在实际代码中真的会更好,这取决于你的应用程序的语言。我不了解你的环境,所以很难推荐,但我知道我肯定会在我的应用层而不是数据库层中这样做。
好处包括更好的可读性,可测试性(您可以编写单元测试以确保您的排名公式按预期工作)等。
答案 1 :(得分:0)
这很有效,但我对其他想法持开放态度:
SELECT UserID, WidgetID, Rank, IsPreferred, Rank() over (Partition BY UserID order by Rank DESC) as Score
FROM dbo.Table
Where IsPreferred = 1
Union
SELECT UserID, WidgetID, Rank, IsPreferred, -1 * Rank() over (Partition BY UserID order by Rank DESC) as Score
FROM dbo.Table
Where IsPreferred = 0
ORDER BY UserID, Score