【问题标题】:postgreSQL ranking query with the given user_id具有给定 user_id 的 postgreSQL 排名查询
【发布时间】:2015-11-28 12:32:59
【问题描述】:

我正在尝试通过二维参数获取用户的排名:donation sum 和 total donor count。

我的排名公式是:rank of [rank of donation_sum + rank of donor_count / 2]

示例表:

donation_id | user_id | donor_id | donation_sum
-----------------------------------------------
1 | 1 | 1 | 10
2 | 1 | 2 | 5
3 | 2 | 3 | 10
4 | 3 | 1 | 50
...

如您所见,有些捐赠者向不同的用户捐款,所以我使用sum(donation_sum) 和count(distinct(donation_id)) 来获得准确的排名

我可以通过捐赠总额和捐赠者总数使用 2 个 sql 分别获得排名列表,但我需要通过 postgreSQL v. 9.4 中给定的user_id 使用上述公式获得用户排名

你有什么解决办法吗?所以我将在 Yii2 PHP 框架中使用该 sql 查询

谢谢


编辑: 我们在 tbl_donation 中添加了donation_date 并修改了实际查询如下:

wheredonation_date 是真的用法吗?

    with list as (
        select 
        s.runner_id, sum, count, rank_sum, rank_count,
        (rank_sum+ rank_count)::float/ 2 as rank_avg,
        row_number() over (order by rank_sum) as rank
    from (
        select *, rank() over (order by sum desc) rank_sum
        from (
            select runner_id, sum(donation_sum)
            from tbl_donation
where donation_date >= '2015-01-01'
            group by 1
            ) s
        ) s
    join (  
        select *, rank() over (order by count desc) rank_count
        from (
            select runner_id, count(distinct(donator_id))
            from tbl_donation
where donation_date >= '2015-01-01'
            group by 1
            ) c
        ) c
    using (runner_id)
    )
    select rank
    from list
    where runner_id = 251;

【问题讨论】:

    标签: php sql postgresql yii2


    【解决方案1】:

    在不同的子查询中进行两个排名:

    select 
        s.user_id, sum, count, rank_sum, rank_count,
        (rank_sum+ rank_count)::float/ 2 as rank_avg,
        row_number() over (order by rank_sum) as rank
    from (
        select *, rank() over (order by sum desc) rank_sum
        from (
            select user_id, sum(donation_sum)
            from donations
            group by 1
            ) s
        ) s
    join (  
        select *, rank() over (order by count desc) rank_count
        from (
            select user_id, count(distinct(donation_id))
            from donations
            group by 1
            ) c
        ) c
    using (user_id);
    
     user_id | sum | count | rank_sum | rank_count | rank_avg | rank 
    ---------+-----+-------+----------+------------+----------+------
           3 | 100 |     1 |        1 |          2 |      1.5 |    1
           1 |  30 |     2 |        2 |          1 |      1.5 |    2
           2 |  20 |     1 |        3 |          2 |      2.5 |    3
    (3 rows)
    

    如果您想为单个user_id 选择rank,请使用with query,例如:

    with list as (
        -- place here the above query
    )
    select rank
    from list
    where user_id = 2;
    

    【讨论】:

    • 感谢您的示例。它在这里工作,它给出了用户等级列表,但这里有些可疑
    • 嘿@klin 你真的让我很开心,谢谢。只是一个问题: row1:rank 1,5 和 row2:rank 1.5 如何为用户获得 1 和 2?例如,其中 user_id = 1 返回 1,5 但对于排名列表,它必须为 2(因为 user_id =3 是排名 1)
    • 它就像我需要行号:) 你可以为行号添加一列吗?谢谢
    • 您可以通过添加row_number()和order by来添加clear排名(作为整数),请参阅编辑后的答案。
    • 我的意思是“喜欢行号”,因为当我使用 where 最后它只返回一行并且它的行号始终为 1 我已将 using (user_id); 更改为 using (user_id) where user_id = 1; @klin 你的解决方案很棒我可以使用 foreach 来获取排名顺序,但我希望不需要它,因为我不会按排名列出用户,我会在他的个人资料页面上显示用户排名; foreach 似乎不是一个好的解决方案。任何的想法?谢谢
    猜你喜欢
    • 1970-01-01
    • 2021-10-01
    • 1970-01-01
    • 2019-10-15
    • 2016-11-15
    • 2019-05-31
    • 1970-01-01
    • 2017-09-04
    • 1970-01-01
    相关资源
    最近更新 更多