Проблем объединения нескольких таблиц

При работе с БД часто возникает ситуация, когда надо вывести данные сразу из нескольких таблиц.

Возьмем любую строчку из таблицы schedule_items

SELECT *
FROM schedule_items
WHERE id = 6204102

увидим что-то такое

посмотрим на поле teacher_id, там значение 4520. Мы уже знаем, что по этому полю можно сходить в таблицу teachers и найти там, кто есть этот 4520

SELECT *
FROM teachers
WHERE id = 4520;

и было, наверное, здорово, если бы могли вместо цифры подставить ФИО преподавателя.

К сожалению, в БД, нет простого решения этой проблемы.

Но есть универсальный подход, построенный на так называемой склейке (объединении) таблиц.

Склейка таблиц через JOIN

Схема такая, берется основная таблица. Допустим возьмем расписание этого 4520, оставим поменьше столбцов чтобы не путаться:

SELECT id, groups, discipline, ngroup, group_id, teacher_id
FROM schedule_items
WHERE teacher_id = 4520 and dbeg = '2023-03-06';

а теперь нам надо каждой строчке из основной таблицы сопоставить строчку из дополнительной. То есть на каждую строчку из основой, мы сопоставляем копию из второстепенной таблицы. Как-то так:

сопоставляем обязательно должно быть по какому-то признаку. В нашем случае это совпадение teacher_id из основной таблицы с id из второстепенной

С точки зрения sql, пишется вот так:

SELECT *
FROM schedule_items
JOIN teachers ON schedule_items.teacher_id = teachers.id
WHERE teacher_id = 4520 and dbeg = '2023-03-06';

получим такое в ответ

Как вывести столбцы с одинаковыми названиями

попробуем теперь оставить только нужные столбцы:

SELECT id, groups, discipline, ngroup, group_id, teacher_id, full_name
FROM schedule_items
JOIN teachers ON schedule_items.teacher_id = teachers.id
WHERE teacher_id = 4520 and dbeg = '2023-03-06';

но при попытке запуска этого запроса увидим такую ошибку

дело в том, что мы указали в SELECT первым столбцом id. А так как мы склеиваем две таблицы и в каждой есть столбец id,

то запрос не понимает какой id имеется ввиду.

Для решения этой проблемы, мы можем явно указать из какой таблицы взять столбец, вот так:

SELECT schedule_items.id, groups, discipline, ngroup, group_id, teacher_id, full_name
FROM schedule_items
JOIN teachers ON schedule_items.teacher_id = teachers.id
WHERE teacher_id = 4520 and dbeg = '2023-03-06';

и тогда запрос запустится уже без ошибок:

в жизни часто бывает, что надо выводить одинаковые поля из разных таблиц, и писать длинные конструкции вида schedule_items становится очень неудобно.

Для удобства в sql можно использовать алисы, чтобы уменьшить длину запроса.

Алиас – это сокращеное названиеи таблицы, которое мы можем прописать прямо в запросе.

Делается это путем добавления сокращения после названия таблицы в конструкции FROM либо в JOIN.

То есть пишем:

FROM schedule_items si

и теперь везде где надо обращаться к таблицу schedule_items можно писать si. Вот так:

SELECT si.id, groups, discipline, ngroup, group_id, teacher_id, full_name
FROM schedule_items si
JOIN teachers t ON si.teacher_id = t.id
WHERE teacher_id = 4520 and dbeg = '2023-03-06';

если захотим добавить идентификатор препода, то можем вытащить его из таблицы teachers.

Так как для нее мы указали алиас t, то достаточно добавить в SELECT:

SELECT si.id, t.id, groups, discipline, ngroup, group_id, teacher_id, full_name
FROM schedule_items si
JOIN teachers t ON si.teacher_id = t.id
WHERE teacher_id = 4520 and dbeg = '2023-03-06';

Склейка не зависит от фильтров

так как склейка происходит глобально по признаку, то если мы сделаем запрос не фильтруя по преподавателю, у нас все равно все имена успешно подтянутся.

SELECT si.id, groups, discipline, ngroup, group_id, teacher_id, full_name
FROM schedule_items si
JOIN teachers t ON si.teacher_id = t.id
WHERE dbeg = '2023-03-06';

Задание

Напишите два запроса:

  1. Запрос который выведет расписание вашей подгруппы на день, когда у вас больше всего пар. Как в предыдущем задании, но вместо номера преподавателя выводите ФИО
  2. Запрос который выведет расписание вашей подгруппы на день, когда у вас больше всего пар. Как в предыдущем задании, но вместо номера аудитории выводите название аудитории