简体   繁体   中英

how to get a sql rank query working to find the rank of a specific id

I try to do a rank query but i fail to get it working correctly. The rank is calculated by the highest market_cap followed by the highest id in case the market_cap has the same value, the condition active must be 1. I only want the rank of a specific id in the end.

Table:

id market_cap active expected rank
1 67000 1 4
2 197000 1 1
3 67000 1 3
4 127000 1 2
5 17000 1 5
6 37000 1 5
7 2237000 0 /

This is the PHP(Laravel) code that does exactly that and is working, but i want to use it as plain SQL for speed improvements since my table has 20k rows.

    $token_list = DB::table('tokens')->where('active', 1)->orderBy('market_cap', 'desc')->orderBy('id', 'desc')->get(array('id'));
    foreach($token_list as $key => $token){
        if($token->id == $data['token']->id){
            $token_rank = $key+1;
        }
    }

Current Query that is not working yet (it stops to work for all results that have a market_cap of 0, which are thousands, they all get the same ranking which is the last rank number):

    $rank_query = DB::select("SELECT FIND_IN_SET(market_cap, ( SELECT GROUP_CONCAT(market_cap ORDER BY market_cap DESC, id DESC) FROM tokens WHERE active = 1)) AS rank FROM tokens WHERE id = {$data['token']->id}");
    $token_rank = $rank_query[0]->rank;

In a SQL query, you can use row_number() :

select t.*
from (select t.*,
             (case when active
                   then row_number() over (partition by active order by market_cap desc, id desc)
              end) as ranking
      from t
     ) t
where . . . 

You would put your filtering conditions in the outer query.

You can do something like this with Laravel's query builder as well. There's no need to use raw sql.

$marketCapQuery = DB::table('tokens')->selectRaw('GROUP_CONCAT(market_cap ORDER BY market_cap DESC, id DESC)'->where('active', 1)->toSql();
$rank_query = DB::table('tokens')->selectRaw("FIND_IN_SET(market_cap, ( '.$marketCapQuery.') AS rank'->where('id', $data['token']->id);
$token_rank = $rank_query[0]->rank;

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM