It is a known trick to use a session variables for dynamically counting/sequencing rows. The way to go is to SET a variable to zero, then use arithmetic within assignment to increment its value for each row in the SELECTed rows.
For example, the following query lists the top 10 populated countries, using MySQL’s world database:
SELECT Code, Name, Population
FROM Country ORDER BY Population DESC LIMIT 10;
+------+--------------------+------------+
| Code | Name | Population |
+------+--------------------+------------+
| CHN | China | 1277558000 |
| IND | India | 1013662000 |
| USA | United States | 278357000 |
| IDN | Indonesia | 212107000 |
| BRA | Brazil | 170115000 |
| PAK | Pakistan | 156483000 |
| RUS | Russian Federation | 146934000 |
| BGD | Bangladesh | 129155000 |
| JPN | Japan | 126714000 |
| NGA | Nigeria | 111506000 |
+------+--------------------+------------+
The results do not provide any sequence number. Nor does the table have an AUTO_INCREMENT or otherwise unique row number. If I were to rate the countries by population, the common trick is:
SET @rank := 0;
SELECT
@rank := @rank+1 AS rank,
Code, Name, Population
FROM Country ORDER BY Population DESC LIMIT 10;
+------+------+--------------------+------------+
| rank | Code | Name | Population |
+------+------+--------------------+------------+
| 1 | CHN | China | 1277558000 |
| 2 | IND | India | 1013662000 |
| 3 | USA | United States | 278357000 |
| 4 | IDN | Indonesia | 212107000 |
| 5 | BRA | Brazil | 170115000 |
| 6 | PAK | Pakistan | 156483000 |
| 7 | RUS | Russian Federation | 146934000 |
| 8 | BGD | Bangladesh | 129155000 |
| 9 | JPN | Japan | 126714000 |
| 10 | NGA | Nigeria | 111506000 |
+------+------+--------------------+------------+
The first query sets the @rank to zero, so that it is not NULL (since no arithmetic can be done with NULL). The second query relies on its success.
Can the same be achieved with one query only? That’s more of a problem. Continue reading » “Dynamic sequencing with a single query”