具有正/负等级的评分公式

时间:2011-12-08 10:22:22

标签: sql sql-server database tsql

我想制作一个我可以在视图中使用的线性分数公式。我在制作逻辑时遇到了麻烦。

数据:

*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。我想PARTITIONRANK可以帮助我,但我还没有成功。

有人有任何想法吗?感谢

更新,请参阅我的回答below

2 个答案:

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