Вы можете использовать переменные для расчета DENSERANK за столом, я предположил, что этот рейтинг будет вновь начать с 1 для каждого комбинации test_id и exam_id которой я отношусь как "partition"
полей, и для этого запроса "value"
мы будем использовать для определения ранга - процент (в порядке убывания); поэтому самый высокий процент получает ранг 1
так:
set @patn = '';
set @rank = 1;
set @valu = '';
set @rept = 1;
SELECT test_id
, exam_id
, user_id
, percentage
, DenseRank
FROM (
SELECT test_id
, exam_id
, user_id
, percentage
, @rank := if(@patn=grp, if(@valu=percentage, @rank, @rank + @rept),1) as DenseRank
, @rept := if(@patn=grp, if(@valu=percentage, @rept, 1),1)
, @patn := grp
, @valu := percentage
FROM (
select
concat(test_id,exam_id) AS grp
, test_id
, exam_id
, user_id
, percentage
from results
order by
test_id
, exam_id
, percentage DESC
) dta
) dtb;
- @patn отслеживает изменения в
"partition"
- @rept отслеживает изменения в
"value"
колонке
- @rept не делает приращение, если
"value"
повторений
- @rank - расчетный плотный ранг
Внутренний запрос (DTA) должны быть отсортированы по:
- в
"partition"
колонн, например, test_id, exam_id
- и столбец
"value"
, например.Процент
Следующий уровень внешнего запроса (DTB),
- сравнивать текущую строку
"partition"
с предыдущей строки "partition"
- если
"partition"
изменений, то ранг = 1
- еще сравнить предыдущую строку
"value"
с текущим рядом "value"
- если
"value"
изменяется, то увеличение ранга на 1
- еще присвоить тот же рейтинг
- текущий
"partition"
сохранен; считается предыдущим "partition"
в следующей строке
- текущий
"value"
сохранен; следует рассматривать предыдущий "value"
на следующей строке
Наконец:
- необходимые столбцы выбраны
Расширение выборочные данные немного это результат:
| TEST_ID | EXAM_ID | USER_ID | PERCENTAGE | DENSERANK |
|---------|---------|---------|------------|-----------|
| 5 | 6 | 580 | 76 | 1 |
| 5 | 6 | 50 | 57 | 2 |
| 5 | 6 | 581 | 57 | 2 |
| 5 | 6 | 582 | 57 | 2 |
| 5 | 6 | 583 | 42 | 3 |
| 5 | 6 | 65 | 42 | 3 |
| 6 | 6 | 580 | 76 | 1 |
Где расчет ранжирования должен только шаг вверх на 1 (отсюда и термин «плотный»), и он возобновляется на одном для следующего «раздела».
нб: термин partition
намекает на partition by
, используемые в системе СУБД, которые действительно имеют аналитические функции для ранжирования (Oracle, DB2, SQL Server, Postgres, другие)
See this SQLfiddle demo