У меня есть таблица training_stats (текущее обучение), а также таблица completed_training.
Что я хочу сделать, так это запросить должное обучение с последней завершенной датой из заполненной таблицы.
У меня почти есть то, что я хочу, я прохожу должное обучение, но они дублируются с каждой завершенной записью (так как есть много завершенных записей для каждой текущей задолженности), и мне нужны только отдельные строки и последняя завершенная дата.
Я пытался использовать MAX, и когда я выполняю запрос MAX независимо, я получаю последнюю запись. Но когда запрос MAX находится в соединении, он возвращает все заполненные строки.
Это запрос, который я использую:
SELECT s.course_stat_id
,o.org_name
,u.id
,u.first_name
,u.last_name
,a.area_id
,a.area_name
,tc.course_id
,tc.course_name
,s.assigned_on
,s.due
,s.pass_mark
,s.completed_on
,completed.complete_training_id
,completed.complete_date
FROM training_stats s
JOIN organisations o ON o.org_id = s.org_id
LEFT JOIN (
SELECT complete_training_id
,user_id
,area_id
,course_id
,max(completed_on) AS complete_date
FROM completed_training
GROUP BY complete_training_id
) completed ON completed.user_id = s.user_id
AND completed.area_id = s.area_id
AND completed.course_id = s.course_id
LEFT JOIN users u ON u.id = s.user_id
LEFT JOIN areas a ON a.area_id = s.area_id
LEFT JOIN training_courses tc ON tc.course_id = s.course_id
WHERE u.active = 1
AND o.active = 1
AND s.assigned = 1
Вы видите, что я делаю неправильно?
Сожалею? Что ты имеешь в виду?
Во внутреннем запросе поместите все столбцы в группу по предложению.
Да, это не имело никакого значения, все еще есть повторяющиеся столбцы
Какую версию MySQL вы используете? Вы можете сделать это с помощью функции ранжирования. Они новы в mysql 8, но для более старой версии можно использовать хитрость.
К сожалению, я использую Mysql 5.6. Я бы подумал, что этот запрос не будет таким сложным :(






Я не уверен в этом на 100%. Сначала запустите этот запрос. Он должен перечислить все завершенные тренировки с rnk от 1 (самый последний) до n (самый старый).
SELECT complete_training_id
,user_id
,area_id
,course_id
,completed_on AS complete_date
,@curRank := case when complete_training_id <> @cur_complete_training_id then 0 else @curRank + 1 end rnk
FROM completed_training, (select @curRank := 0, @cur_complete_training_id := 0)
ORDER BY complete_training_id, completed_on DESC
Если это правда, то ответ таков:
SELECT s.course_stat_id
,o.org_name
,u.id
,u.first_name
,u.last_name
,a.area_id
,a.area_name
,tc.course_id
,tc.course_name
,s.assigned_on
,s.due
,s.pass_mark
,s.completed_on
,completed.complete_training_id
,completed.complete_date
FROM training_stats s
JOIN organisations o ON o.org_id = s.org_id
LEFT JOIN (
SELECT complete_training_id
,user_id
,area_id
,course_id
,completed_on AS complete_date
,@curRank := case when complete_training_id <> @cur_complete_training_id then 0 else @curRank + 1 end rnk
FROM completed_training, (select @curRank := 0, @cur_complete_training_id := 0)
ORDER BY complete_training_id, completed_on DESC
) completed ON completed.user_id = s.user_id and completed.rnk = 1
AND completed.area_id = s.area_id
AND completed.course_id = s.course_id
LEFT JOIN users u ON u.id = s.user_id
LEFT JOIN areas a ON a.area_id = s.area_id
LEFT JOIN training_courses tc ON tc.course_id = s.course_id
WHERE u.active = 1
AND o.active = 1
AND s.assigned = 1
Очень признателен за вашу помощь. Я получаю эту ошибку, когда пытаюсь запустить этот запрос: # 1248 - Каждая производная таблица должна иметь собственный псевдоним
добавить псевдоним после (select @curRank := 0, @cur_complete_training_id := 0)
Не совсем положительный из ваших ожидаемых результатов, но провал, ВЕРОЯТНО, для вашей группы, и ПРИСОЕДИНЯЙТЕСЬ. Ваша группа указана ТОЛЬКО на идентификаторе обучения, но вы также выбираете пользователя, область и курс, а также максимальную дату завершения для указанного соответствующего идентификатора обучения, пользователя, области, курса. Вы группируете по и присоединяете должны соответствовать уникальным характеристикам.
Не видя данных, запрос, как я его понимаю, состоит в том, что "complete_training_id" является столбцом с автоматическим приращением для этой таблицы. Сказав это, для этого идентификатора будет только одна запись.
При этом в готовой тренировочной таблице для одного пользователя, области и курса может быть несколько дней обучения, из которых вы хотите получить самый последний. Например, кто-то учится в колледже и должен посещать много компьютерных классов, и они являются новичками по сравнению с предыдущими, поэтому предположим, что все имеют один и тот же идентификатор курса. Человек может пройти в 2012, 2014, 2016 годах. Вам нужен экземпляр пользователя / области / курса, показывающий обучение, датированное 2016 годом. Итак, давайте сначала посмотрим на это.
select
ct.user_id,
ct.area_id,
ct.course_id,
max(ct.completed_on) AS complete_date
FROM
completed_training ct
GROUP BY
ct.user_id,
ct.area_id,
ct.course_id
Теперь для каждого пользователя, области и курса обучения у меня есть одна запись с самой последней датой завершения. СЕЙЧАС позвольте вытащить остальные детали, но, поскольку вам также нужен идентификатор завершенного обучения, я применил его MAX () в запросе ниже. По умолчанию идентификатор должен увеличиваться каждый раз, когда добавляется новая запись, поэтому запись, завершенная год назад, будет иметь меньшее значение, чем идентификатор, завершенный сегодня. Таким образом, вы получаете как заполненный идентификатор, так и соответствующую дату для данного пользователя, области, курса.
SELECT
s.course_stat_id,
o.org_name,
u.id,
u.first_name,
u.last_name,
a.area_id,
a.area_name,
tc.course_id,
tc.course_name,
s.assigned_on,
s.due,
s.pass_mark,
s.completed_on,
ct.complete_training_id,
ct.complete_date
FROM
training_stats s
JOIN organisations o
ON s.org_id = o.org_id
AND o.active = 1
LEFT JOIN
( select
ct.user_id,
ct.area_id,
ct.course_id,
max(ct.complete_training_id ) as complete_training_id,
max(ct.completed_on) AS complete_date
FROM
completed_training ct
GROUP BY
ct.user_id,
ct.area_id,
ct.course_id ) ct
on s.user_id = ct.user_id
AND s.area_id = ct.area_id
AND s.course_id = ct.course_id
JOIN users u
ON s.user_id = u.id
AND u.active = 1
LEFT JOIN areas a
ON s.area_id = a.area_id
LEFT JOIN training_courses tc
ON s.course_id = tc.course_id
WHERE
s.assigned = 1
Почему вы не сгруппировали свой внутренний запрос с user_id, area_id, course_id?