With MySQL, how can I generate a column containing the record index in a table?

前端 未结 8 1770
轻奢々
轻奢々 2020-11-21 23:57

Is there any way I can get the actual row number from a query?

I want to be able to order a table called league_girl by a field called score; and return the username

相关标签:
8条回答
  • 2020-11-22 00:37

    Assuming MySQL supports it, you can easily do this with a standard SQL subquery:

    select 
        (count(*) from league_girl l1 where l2.score > l1.score and l1.id <> l2.id) as position,
        username,
        score
    from league_girl l2
    order by score;
    

    For large amounts of displayed results, this will be a bit slow and you will want to switch to a self join instead.

    0 讨论(0)
  • 2020-11-22 00:38

    Here comes the structure of template I used:

      select
              /*this is a row number counter*/
              ( select @rownum := @rownum + 1 from ( select @rownum := 0 ) d2 ) 
              as rownumber,
              d3.*
      from 
      ( select d1.* from table_name d1 ) d3
    

    And here is my working code:

    select     
               ( select @rownum := @rownum + 1 from ( select @rownum := 0 ) d2 ) 
               as rownumber,
               d3.*
    from
    (   select     year( d1.date ), month( d1.date ), count( d1.id )
        from       maindatabase d1
        where      ( ( d1.date >= '2013-01-01' ) and ( d1.date <= '2014-12-31' ) )
        group by   YEAR( d1.date ), MONTH( d1.date ) ) d3
    
    0 讨论(0)
  • 2020-11-22 00:39

    I found the original answer incredibly helpful but I also wanted to grab a certain set of rows based on the row numbers I was inserting. As such, I wrapped the entire original answer in a subquery so that I could reference the row number I was inserting.

    SELECT * FROM 
    ( 
        SELECT *, @curRow := @curRow + 1 AS "row_number"
        FROM db.tableName, (SELECT @curRow := 0) r
    ) as temp
    WHERE temp.row_number BETWEEN 1 and 10;
    

    Having a subquery in a subquery is not very efficient, so it would be worth testing whether you get a better result by having your SQL server handle this query, or fetching the entire table and having the application/web server manipulate the rows after the fact.

    Personally my SQL server isn't overly busy, so having it handle the nested subqueries was preferable.

    0 讨论(0)
  • 2020-11-22 00:39

    I know the OP is asking for a mysql answer but since I found the other answers not working for me,

    • Most of them fail with order by
    • Or they are simply very inefficient and make your query very slow for a fat table

    So to save time for others like me, just index the row after retrieving them from database

    example in PHP:

    $users = UserRepository::loadAllUsersAndSortByScore();
    
    foreach($users as $index=>&$user){
        $user['rank'] = $index+1;
    }
    

    example in PHP using offset and limit for paging:

    $limit = 20; //page size
    $offset = 3; //page number
    
    $users = UserRepository::loadAllUsersAndSortByScore();
    
    foreach($users as $index=>&$user){
        $user['rank'] = $index+1+($limit*($offset-1));
    }
    
    0 讨论(0)
  • 2020-11-22 00:48
    SELECT @i:=@i+1 AS iterator, t.*
    FROM tablename t,(SELECT @i:=0) foo
    
    0 讨论(0)
  • 2020-11-22 00:52

    You can also use

    SELECT @curRow := ifnull(@curRow,0) + 1 Row, ...
    

    to initialise the counter variable.

    0 讨论(0)
提交回复
热议问题