58

Here is my MySQL query:

SELECT name FROM table;

How can I also select an increment counter alongside name? Expected output:

Jay 1
roy 2
ravi 3
ram 4
reformed
  • 4,505
  • 11
  • 62
  • 88
iJade
  • 23,144
  • 56
  • 154
  • 243

5 Answers5

140
select name,
      @rownum := @rownum + 1 as row_number
from your_table
cross join (select @rownum := 0) r
order by name

This part:

cross join (select @rownum := 0) r

makes it possible to introduce a variable without the need of a seperate query. So the first query could also be broken down into two queries like this:

set @rownum := 0;

select name,
      @rownum := @rownum + 1 as row_number
from your_table
order by name;

for instance when used in a stored procedure.

juergen d
  • 201,996
  • 37
  • 293
  • 362
  • 3
    As Fabio Reche was trying to say, we need to write it with a '@' in front of `rownum + 1`...isn't it suppose to be `@rownum := @rownum + 1` ? – ghiscoding Jan 17 '14 at 19:42
  • 1
    Thanks, +1 for `CROSS JOIN`, solved anther problem when I need group by clausule (map/reduce) – Ragen Dazs Jun 24 '16 at 20:44
  • The subrequest is used to intializing @rownum. – Genjo Aug 04 '16 at 15:34
  • 1
    This solution doesn't work properly if you sort values. Counter increments for unsorted rows. – Paktas Oct 02 '17 at 10:34
  • @Paktas: I have no idea what are you talking about. Could you elaborate? – juergen d Oct 02 '17 at 12:24
  • Reading & writing the same variable in the same select statement is undefined behaviour in MySQL. – philipxy Aug 28 '19 at 23:21
  • @philipxy: You got a source for that? – juergen d Aug 29 '19 at 06:09
  • Read the manual sections pre-8.0 on user variables & assignment. 8,0 explicitly deprecates it. Also google my SO comments re this (with & without 'percona'). But if you don't have an authoratative source saying it's ok, you shouldn't be saying that it is. – philipxy Aug 29 '19 at 19:47
22

In MySQL 8 and above you can also use the ROW_NUMBER() Window function.

SELECT
    name,
    ROW_NUMBER() OVER ()
FROM table

Result:

Jay  1
roy  2
ravi 3
ram  4

As shown by juergen d, it would be a good idea to put an ORDER BY to have a deterministic query.

The ORDER BY can apply to the query and the counter independently. So:

SELECT
    name,
    ROW_NUMBER() OVER (ORDER BY name DESC)
FROM table
ORDER BY name

would give you a counter in decreasing order.

Result:

Jay  4
ram  3
ravi 2
roy  1
juergen d
  • 201,996
  • 37
  • 293
  • 362
user11415449
  • 221
  • 2
  • 2
12
SELECT name,
      @rownum := @rownum + 1 as row_number
FROM your_table
   ,
   (select @rownum := 0) r

I prefer using a comma instead of CROSS JOIN as it performs faster. Using CROSS JOIN will add one extra step of adding a column to your table.

Selaka Nanayakkara
  • 3,296
  • 1
  • 22
  • 42
Nili Waypa
  • 121
  • 1
  • 5
  • 2
    Very interesting. Could you explain this syntax? This solved a problem I was having with a counter over grouped items where the results were not consistent. At the console int he same session, the first run returned all 1s then from the second run it worked okay. So it never worked as a script. Until I removed the initial set @var commands and used your method. Now it works consistently! – Chris Njuguna Jul 08 '20 at 10:50
  • 1
    @ChrisNjuguna: The syntax is the old legacy SQL join syntax where you comma separate the tables you want to join. – juergen d Apr 30 '22 at 13:12
3

Solutions with cross join and comma won't work if your query has GROUP BY statement. For such cases you can use subselect:

SELECT (@row_number := @row_number + 1) AS rowNumber, res.*
FROM
(
  SELECT SUM(r.amount) 
  FROM Results r 
  WHERE username = 1 
  GROUP BY r.amount
) res
CROSS JOIN (SELECT @row_number := 0) AS dummy
Eugene Maysyuk
  • 2,977
  • 25
  • 24
0

Has anyone ever face this case, where I query

select name,
  @rownum := @rownum + 1 as row_number
from your_table
cross join (select @rownum := 0) r
order by name desc;

the result is

roy  4
ravi 3
ram  2
jay  1

but what I want is

roy  1
ravi 2
ram  3
jay  4

when I query in mariadb version 10.5.9 the result is like what I want, but when I trial in mariabd version 10.6.10 or 10.9.2 , the result not I expected.

Tryanto I
  • 11
  • 3
  • As it’s currently written, your answer is unclear. Please [edit] to add additional details that will help others understand how this addresses the question asked. You can find more information on how to write good answers [in the help center](/help/how-to-answer). – Community Sep 07 '22 at 02:51