【问题标题】:Create a ranking for user为用户创建排名
【发布时间】:2016-11-15 03:28:42
【问题描述】:

我的数据库中有很多用户

User -- Points
user1   4
user2   6
user3   2
user4   3
user5   8
user6   9
user7   1
user8   5

我正在寻找最简单且错误更少的方法来为特定用户创建 5 级。我选择的用户应该在中间,顶部有 2 个,底部有 2 个。

示例 1:user8 我应该收到:

user5   8
user2   6
**user8 5**
user1   4
user4   3

示例 2:user4 我应该收到:

user8   5
user1   4
**user4 3**
user3   2
user7   1

比我有例外。如果用户是TOP1,我需要显示下4 示例:用户 6

**user6 9**
user5   8
user2   6
user8   5
user1   4

(如果 user 是 LAST 也会发生同样的情况,所以在这种情况下我需要接下来的 4 个用户。

有人知道一个简单的方法吗?

编辑:我没有要求任何人为我做这件事。我在问提示。 我不明白反对票。这只是一个问题。

【问题讨论】:

  • 到目前为止你尝试过什么?我建议先过滤,然后检查您要查看的用户上方是否有两个用户。
  • 如果只有 3 个用户呢?
  • @depperm 我想过,但在那种情况下,我必须考虑所有可能的情况。我想知道是否有一些简单的方法
  • @JuanCarlosOropeza 如果只有 3 个用户,在这种情况下,我会使用相同的规则显示所选用户的 3 个用户。如果只有 1 个用户,我只显示该用户

标签: python django postgresql django-rest-framework


【解决方案1】:

我在 sql server 上做,但在 postgresql 上也一样。我现在都包含了。

  • 检查Rank()函数,看看如何处理关系或使用row_number()
  • 使用变量而不是'user3'

Postgres Demo
SQL Fiddle Demo

WITH playerPoint as (
    SELECT "points"
    FROM Table1
    WHERE "user" = 'user3'
)    
SELECT *
FROM (
        SELECT *
        FROM (
                SELECT T."user", 
                       T."points", 
                       CASE WHEN T."points" = P."points"
                            THEN '*****' 
                            ELSE ''
                       END as Selected,
                       RANK() OVER (ORDER BY T."points" DESC) ranking

                FROM       Table1 T
                CROSS JOIN playerPoint P
                WHERE T."points" <= P."points"
                UNION
                SELECT T."user", 
                       T."points",
                       CASE WHEN T."points" = P."points"
                            THEN '*****' 
                            ELSE ''
                       END as Selected,
                       RANK() OVER (ORDER BY T."points" ASC) ranking

                FROM       Table1 T
                CROSS JOIN playerPoint P
                WHERE T."points" >= P."points"

        ) R1
        ORDER BY ranking
        LIMIT 5
     ) R2
ORDER BY POINTS

输出

在将DESC 添加到最后一个ORDER BYuser8 之后

【讨论】:

  • 嗨@Juan。谢谢,但那里有问题。我选择的用户应该在查询给出的 5 个用户的中间。所以在你发布的这个例子中,对于 user8 应该是这样的: user5 8 user2 6 user8 5 user1 4 user4 3
  • @VaoTsun 我把它放在开头......是sql server,所以我可以测试它。但是sintaxis是一样的。
  • @62009030 是的,我没有包含额外的ORDER BY,请查看我的更新。我将示例更改为user3
  • @VaoTsun 我现在包含了 Postgres 的小提琴,你也可以用它来尝试你的代码。
  • 我认为 postgres 小提琴不正确。 SQL server 正确
【解决方案2】:

这里t5 是您的表,u 是包含用户的列,r 是包含点的列...我尝试使用用户值 'u4' - 尝试使用您的...

select u,r from (
select *, case when l2 = 'u4' or r1 > 0 or r < max(ur) over () then 1 else 0 end r2 from (
select *, case when l1 = 'u4' or r0 > 0 then 2 else 0 end r1, lag(l1) over (order by r) l2 from (
select *
    --, row_number() over (order by r)
    , lag(u) over (order by r) l1
    , case when u = 'u4' then r else 0 end ur
    --, count(*) over () 
    , case when u = 'u4' then 3 else 0 end r0
from t5 
order by r desc 
) prim
order by r desc 
) sec
) ter
where r2 > 0
order by r desc 
limit 5

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2011-02-28
    • 1970-01-01
    • 1970-01-01
    • 2013-06-29
    相关资源
    最近更新 更多