【问题标题】:how to find out the rank of a row based on a mysql sum?如何根据mysql总和找出一行的排名?
【发布时间】:2009-09-13 04:35:45
【问题描述】:

我想查找行的排名/编号。我不确定我是否解释得很好,所以我会尝试。

我有问题

$sql = 'SELECT SUM(amount) AS total FROM sales ORDER BY total DESC';

$res = mysql_query($sql);

while($row = mysql_fetch_array($res)) {

// go through and print each row biggest 'total' first
echo $row['total'] . '<br />';

}

现在我想根据最大的“总数”为“1”给每个人一个排名。

所以我可以用 php 做一些计数:

$sql = 'SELECT SUM(amount) AS total FROM sales ORDER BY total DESC';

$res = mysql_query($sql);

$rank = 1;

while($row = mysql_fetch_array($res)) {



// go through and print each row biggest 'total' first
echo 'rank: ' . $rank . ', ' . $row['total'] . '<br />';

$rank = $rank + 1;

}

这很好并且有效。但是我想要做的是能够在没有 php 的情况下确定行的排名,这样我就可以根据销售表中的会员 ID 进行 sql 查询。

例如,我有 100 行销售数据,每行都有一个关联 ID,我将如何简单地根据总数最大的关联获得排名?

【问题讨论】:

    标签: php sql mysql


    【解决方案1】:

    您可以使用递归变量来执行此操作,如下所示:

    select 
        @rownum:=@rownum+1 as rank,
        sum(amount) as total
    from 
        sales,
        (select @rownum:=0) a
    order by total desc
    

    要获取给定会员的排名,您必须这样做:

    select
        a.*,
        t.rank,
        t.total
    from
        affiliates a
        inner join (
            select 
                @rownum:=@rownum+1 as rank,
                affiliate_id,
                sum(amount) as total
            from 
                sales,
                (select @rownum:=0) r
            group by affiliate_id
            order by total desc) t on
           a.affiliate_id = t.affiliate_id
    where
        a.affiliate_id = 342
    

    现在这(相对)很慢,因为您每次都必须进行表扫描。

    如果您不使用 MySQL,我建议使用子查询,但总的来说,MySQL 对子查询的优化非常糟糕。对我来说它似乎相当慢,但我没有对其进行基准测试。无论如何,您可以这样做:

    select
        a.*,
        (select
            count(*)+1
        from
            (select affiliate_id from sales 
             group by affiliate_id having sum(amount) >
                (select sum(amount) from sales where affiliate_id = a.affiliate_id)))
            as rank
    from
        affiliates a
    where
        a.affiliate_id = 342
    

    【讨论】:

    • @Mauris:不,没有任何意义。可能是一两毫秒的开销,但我不能说,因为我已经对其进行了基准测试(从未觉得有必要)。
    • 很抱歉,我不明白如何使用上述内容仅提取我的一个附属公司的排名。我会在什么时候输入'WHERE associateID="342"'?感谢您的宝贵时间!
    • @Mauris:我应该详细说明这不是递归的命令意义。虽然它引用自己,但在满足条件之前它不会调用自己。它只是调用它的最后一个已知值。这更类似于for(int i = 0; i &lt; 10; i++) rownum++; 而不是int rownum(int place) { if (place &gt;= 10) return place; else rownum(place+1); }
    • 太棒了。辛苦了!这确实需要一段时间,所以我想我会运行一个每小时 cron 并每小时更新一个排名列,这样这个 sql 就不会一直运行。
    【解决方案2】:

    DB 的其他实现有 row_number 和 row_number_count。如果你使用 MySQL,建议你看看这个walk-around

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2018-11-05
      • 2017-03-14
      • 1970-01-01
      • 1970-01-01
      • 2017-03-21
      • 2021-08-04
      • 2019-12-06
      相关资源
      最近更新 更多