Номер строки MySQL для каждой группы с групповой памятью
Я выполняю запущенную программу в Java и MySQL. Таким образом, у бегунов может быть статистика того, кто на первом месте после окончания гонки. Также бегуны расы по категории. Так что есть и победители по каждой категории. Все данные находятся в отдельных таблицах в MySQL, и когда гонки заканчиваются, запрос должен показывать общую позицию таблицы и по категориям, в зависимости от того, насколько быстро они заканчиваются.
У меня эти таблицы в MySQL:
events (id, name, isActive)
runners (id, name, sex)
category (id, name, isActive)
inscriptions (id, event_id, runner_id, category, number_assigned, isActive)
race (id, inscription_id, start, end)
И у меня есть этот запрос, который дает мне позицию в таблице после окончания гонки.
SELECT category.'name' AS 'CATEGORÍA', inscriptions.number_assigned AS 'NÚMERO', runners.name AS 'COMPETIDOR', runners.sex AS 'SEXO', races.'start' AS 'INICIO', races.'end' AS 'FIN', SEC_TO_TIME(UNIX_TIMESTAMP(races.'end') - UNIX_TIMESTAMP(races.'start')) AS 'TIEMPO'
FROM 'events'
INNER JOIN 'inscriptions' ON inscriptions.event_id = 'events'.id
INNER JOIN 'races' ON races.inscription_id = inscriptions.id
INNER JOIN 'category' ON inscriptions.category = category.id
INNER JOIN 'runners' ON inscriptions.runner_id = runners.id
WHERE 'events'.id = 1
AND inscriptions.isFinished = 0
AND 'events'.isActive = 1
AND 'inscriptions'.isActive = 1
AND 'category'.isActive = 1
AND 'runners'.isActive = 1
ORDER BY races.'end' IS NULL, SEC_TO_TIME(UNIX_TIMESTAMP(races.'end') - UNIX_TIMESTAMP(races.'start')) ASC;
Причина этого первого запроса заключается в том, что мне нужна информация о позиции таблицы. Я включаю "race.end IS NULL" в групповом оговорке, потому что мне нужно бегунов без окончания времени (не заканчивая гонку) в конце таблицы.
Это дает мне следующий результат:
ОК. Если я попытаюсь выполнить обычную процедуру добавления "номера строки", все получилось беспорядок, потому что запрос сначала присваивает номер строке, а затем применяет в нем предложение.
SELECT
@r := @r+1 AS 'POSICION',
'category'.'name' AS 'CATEGORÍA',
'inscriptions'.'number_assigned' AS 'NÚMERO',
'runner'.'name' AS 'COMPETIDOR',
'runners'.'sex' AS 'SEXO',
'races'.'start' AS 'INICIO',
'races'.'end' AS 'FIN',
SEC_TO_TIME(UNIX_TIMESTAMP('races'.'end') - UNIX_TIMESTAMP('races'.'start')) AS 'TIEMPO'
FROM
(SELECT @r:=0)y, 'events'
INNER JOIN 'inscriptions' ON ('inscriptions'.'event_id' = 'events'.'id')
INNER JOIN 'races' ON ('races'.'inscription_id' = 'inscriptions'.'id')
INNER JOIN 'category' ON ('inscriptions'.'category' = 'category'.'id')
INNER JOIN 'runners' ON ('inscriptions'.'runner_id' = 'runners'.'id')
WHERE
'events'.'id' = 1 AND
'inscriptions'.'isFinished' = 0 AND
'events'.'isActive' = 1 AND
'inscriptions'.'isActive' = 1 AND
'category'.'isActive' = 1 AND
'runners'.'isActive' = 1 AND
'races'.'end' IS NOT NULL
ORDER BY
'races'.'end' IS NULL,
SEC_TO_TIME(UNIX_TIMESTAMP('races'.'end') - UNIX_TIMESTAMP('races'.'start')) ASC;
И беспорядок везде:
ОК. По прошествии некоторого времени в поиске я делаю запрос, чтобы получить свою "позицию таблицы", а затем перекрещиваю его с другим, чтобы поставить номер строки до сих пор. Работает отлично.
Теперь проблема категории.
Когда вы пытаетесь сделать то же самое с системой категорий, запрос только подсчитывает последовательную последовательность номера, в категории нет памяти, например "10 строк назад, где другой мастер в 4 позиции, поэтому это должно быть 5". Более конкретно, прикрепите код того, что не так и что должно быть.
НЕПРАВИЛЬНО:
1 1 Especiales Especiales 614 Alex Chancusi M 2016-10-09 07:12:53 2016-10-09 07:32:16 00:19:23
2 1 Juvenil Juvenil 491 Anthony Recalde Carrillo M 2016-10-09 07:12:53 2016-10-09 07:35:34 00:22:41
3 1 Master Master 610 Marco Almache M 2016-10-09 07:12:53 2016-10-09 07:35:50 00:22:57
4 1 Senior Senior 632 Cristian Rafael Caizapanta M 2016-10-09 07:12:53 2016-10-09 07:36:17 00:23:24
5 2 Senior Senior 138 Dennys Morocho Guayanlema M 2016-10-09 07:12:53 2016-10-09 07:37:00 00:24:07
6 1 Master Master 591 Manuel Suntaxi M 2016-10-09 07:12:53 2016-10-09 07:37:35 00:24:42
7 1 Senior Senior 508 Jhon Robles M 2016-10-09 07:12:53 2016-10-09 07:38:44 00:25:51
8 2 Senior Senior 536 Margaret Karic Zoroitich F 2016-10-09 07:12:53 2016-10-09 07:38:53 00:26:00
9 3 Senior Senior 538 Carlos Moreno M 2016-10-09 07:12:53 2016-10-09 07:39:20 00:26:27
10 1 Master Master 550 Luis Toaquiza M 2016-10-09 07:12:53 2016-10-09 07:39:43 00:26:50
Неправильно, потому что, если вы видите в позиции 3, есть "Мастер" с первым местом, а затем позиция 6 другой "Мастер" с одинаковым положением и то же самое в 10 позиции.
ХОРОШО:
1 1 Especiales Especiales 614 Alex Chancusi M 2016-10-09 07:12:53 2016-10-09 07:32:16 00:19:23
2 1 Juvenil Juvenil 491 Anthony Recalde Carrillo M 2016-10-09 07:12:53 2016-10-09 07:35:34 00:22:41
3 1 Master Master 610 Marco Almache M 2016-10-09 07:12:53 2016-10-09 07:35:50 00:22:57
4 1 Senior Senior 632 Cristian Rafael Caizapanta M 2016-10-09 07:12:53 2016-10-09 07:36:17 00:23:24
5 2 Senior Senior 138 Dennys Morocho Guayanlema M 2016-10-09 07:12:53 2016-10-09 07:37:00 00:24:07
6 2 Master Master 591 Manuel Suntaxi M 2016-10-09 07:12:53 2016-10-09 07:37:35 00:24:42
7 3 Senior Senior 508 Jhon Robles M 2016-10-09 07:12:53 2016-10-09 07:38:44 00:25:51
8 4 Senior Senior 536 Margaret Karic Zoroitich F 2016-10-09 07:12:53 2016-10-09 07:38:53 00:26:00
9 5 Senior Senior 538 Carlos Moreno M 2016-10-09 07:12:53 2016-10-09 07:39:20 00:26:27
10 3 Master Master 550 Luis Toaquiza M 2016-10-09 07:12:53 2016-10-09 07:39:43 00:26:50
И так далее. Всегда есть другое название категории, поэтому список категорий не является правильным решением.
Конечный запрос, используемый для этого результата:
SELECT @posGeneral := CASE WHEN z.'FIN' IS NULL THEN 'Not finished yet' ELSE @posGeneral+1 END AS 'POS GENERAL',
@posCat := CASE WHEN z.'FIN' IS NULL THEN '-' ELSE CASE WHEN @cat = z.'CATEGORÍA' THEN @posCat + 1 ELSE 1 END END AS 'POS CATEGORÍA',
@cat := z.'CATEGORÍA' AS 'CAT',
z.* FROM(
SELECT
'category'.'name' AS 'CATEGORÍA',
'inscriptions'.'number_assigned' AS 'NÚMERO',
'runner'.'name' AS 'COMPETIDOR',
'runners'.'sex' AS 'SEXO',
'races'.'start' AS 'INICIO',
'races'.'end' AS 'FIN',
SEC_TO_TIME(UNIX_TIMESTAMP('races'.'end') - UNIX_TIMESTAMP('races'.'start')) AS 'TIEMPO'
FROM
'events'
INNER JOIN 'inscriptions' ON ('inscriptions'.'event_id' = 'events'.'id')
INNER JOIN 'races' ON ('races'.'inscription_id' = 'inscriptions'.'id')
INNER JOIN 'category' ON ('inscriptions'.'category' = 'category'.'id')
INNER JOIN 'runners' ON ('inscriptions'.'runner_id' = 'runners'.'id')
WHERE
'events'.'id' = 1 AND
'inscriptions'.'isFinished' = 1 AND
'events'.'isActive' = 1 AND
'inscriptions'.'isActive' = 1 AND
'category'.'isActive' = 1 AND
'runners'.'isActive' = 1
ORDER BY
'races'.'end' IS NULL,
SEC_TO_TIME(UNIX_TIMESTAMP('races'.'end') - UNIX_TIMESTAMP('races'.'start')) ASC
)z, (SELECT @posGeneral:=0, @posCat:=0)y;
Ничего, я просто нахожу, как это сделать...
Это что-то связано с тем, как MySQL понимает запрос и как обрабатывает запрос для результатов...
Jus немного играет с предложением ORDER и добавляет новый уровень в запрос z., Y. и х. *
z. * для номера строки y. * для позиции категории (по категориям) x. * исходный запрос.
Спасибо, в любом случае.