Зависимая таблица

Теперь немного усложним наши запросы. Добавим в нашу базу данных новую таблицу task с задачами для наших сотрудников. И посмотрим, какие в ней есть записи:


SELECT * FROM task 

Результат такого запроса:

id emploee_id name deadline
1 1 Исправить багу на фронтенде 2022-06-01
2 2 Исправить багу на бэкенде 2022-06-15
3 5 Купить кофе 2022-07-01
4 5 Купить кофе 2022-08-01
5 5 Купит кофе 2022-09-01
6 (NULL) Убрать офис (NULL)
7 4 Наслаждаться жизнью (NULL)
8 6 Наслаждаться жизнью (NULL)

В этой таблице есть всего 4 колонки:

  • id — уникальный номер задания (и строки в таблице);
  • employee_id — ID сотрудника из таблицы employee, на которого назначена задача;
  • name — название и описание задачи;
  • deadline — время до которого нужно выполнить задачу.

Обрати внимание на несколько нюансов. Задача N6 не имеет employee_id, у нас нет уборщицы. Задача есть, а исполнителя нет. Такое бывает.

Также у задач 6-9 нет установленного дедлайна. Такое бывает, когда задача должна делаться регулярно и беспрерывно. Например, офис нужно убирать каждый день, ну и наслаждаться жизнью тоже нужно каждый день :)

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

Запрос к нескольким таблицам

Вот мы видим в таблице task, что есть два задания “Наслаждается жизнью”. Как нам узнать, кто именно эти счастливчики?

Для этого в SQL можно выполнить запрос сразу к двум таблицам. Вообще в SQL можно выполнять запрос к любому количеству таблиц одновременно. Общий формат такого запроса:

SELECT колонки 
FROM таблица1, таблица2, таблицаN

Важно! Если ты напишешь запрос к нескольким таблицам одновременно, то в результате получишь так называемое декартово произведение строк таблиц. К каждой строке из первой таблицы будет приклеена каждая строка из второй таблицы и так далее.

То есть если в первой таблице у вас 5 строк, а во второй 10, то всего у вас будет 50 строк. На языке Java этот запрос выглядел бы примерно так:


for (String row1 : table1) 
{ 
	for (String row2 : table2)  
   { 
  	System.out.println(row1 + row2); 
   }  
} 

Давай напишем наш запрос сразу к двум таблицам и посмотрим, что получится:


SELECT * FROM employee, task

И результат такого запроса:

id name occupation salary age id emploee_id name deadline
1 Иванов Иван Программист 100000 25 1 1 Исправить багу на фронтенде 2022-06-01
2 Петров Петр Программист 80000 23 1 1 Исправить багу на фронтенде 2022-06-01
3 Иванов Сергей Тестировщик 40000 30 1 1 Исправить багу на фронтенде 2022-06-01
4 Рабинович Мойша Директор 200000 35 1 1 Исправить багу на фронтенде 2022-06-01
5 Кириенко Анастасия Офис-менеджер 40000 25 1 1 Исправить багу на фронтенде 2022-06-01
6 Васька кот 1000 3 1 1 Исправить багу на фронтенде 2022-06-01
1 Иванов Иван Программист 100000 25 2 2 Исправить багу на бэкенде 2022-06-15
2 Петров Петр Программист 80000 23 2 2 Исправить багу на бэкенде 2022-06-15
3 Иванов Сергей Тестировщик 40000 30 2 2 Исправить багу на бэкенде 2022-06-15
4 Рабинович Мойша Директор 200000 35 2 2 Исправить багу на бэкенде 2022-06-15
5 Кириенко Анастасия Офис-менеджер 40000 25 2 2 Исправить багу на бэкенде 2022-06-15

Всего строк результата у нас 48, но тут я привел всего 11. Иначе просто места не хватит.

Обрати внимание на три вещи:

  • Колонки с одинаковыми именами: id. Это id из таблицы employee и id из таблицы task.
  • Строки каждой таблицы повторяются. В левой колонке после ID 6 снова идет ID = 1.
  • У нас есть бессмысленные строки, когда, например id (из таблицы employee) равно 6 и в той же строке employee_id равно 1.

Убираем бессмысленные строки

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

Логично, что если в строке employee_id равно 3, то она должна приклеиваться только к строке из таблицы employee, где id равно 3. Давай попробуем исправить это недоразумение с помощью WHERE.

Напишем такой запрос:

SELECT * FROM employee, task 
WHERE emploee.id = task.emploee_id 

И результат такого запроса:

id name occupation salary age id emploee_id name deadline
1 Иванов Иван Программист 100000 25 1 1 Исправить багу на фронтенде 2022-06-01
2 Петров Петр Программист 80000 23 2 2 Исправить багу на бэкенде 2022-06-15
4 Рабинович Мойша Директор 200000 35 7 4 Наслаждаться жизнью (NULL)
5 Кириенко Анастасия Офис-менеджер 40000 25 3 5 Купить кофе 2022-07-01
5 Кириенко Анастасия Офис-менеджер 40000 25 4 5 Купить кофе 2022-08-01
5 Кириенко Анастасия Офис-менеджер 40000 25 5 5 Купит кофе 2022-09-01
6 Васька кот 1000 3 8 6 Наслаждаться жизнью (NULL)

Хорошая новость — у нас исчезли бессмысленные строки: id из первой колонки всегда равно employee_id.

Плохая новость — исчезли задачи, которые ни на кого не назначены, такие как уборка офиса. Их employee_id был равен NULL, поэтому они были отброшены после выполнения WHERE.

undefined
1
Задача
Модуль 4. Работа с БД, 3 уровень, 0 лекция
Недоступна
task0301
Выбрать все колонки (используй *) из таблиц gyms и customers.
undefined
1
Задача
Модуль 4. Работа с БД, 3 уровень, 0 лекция
Недоступна
task0302
Требуется найти все записи из таблиц gyms и customers, где location равно London. Используй WHERE.
undefined
1
Задача
Модуль 4. Работа с БД, 3 уровень, 0 лекция
Недоступна
task0303
Требуется найти все записи из таблиц gyms и customers, где name из таблицы gyms равно name из таблицы customers. Используй WHERE.
undefined
1
Задача
Модуль 4. Работа с БД, 3 уровень, 0 лекция
Недоступна
task0304
Требуется найти колонки name и location из таблицы gyms, и колонки sex и location из таблицы customers.
undefined
1
Задача
Модуль 4. Работа с БД, 3 уровень, 0 лекция
Недоступна
task0305
Требуется найти колонки id и name из таблицы gyms, и колонки name и email из таблицы customers, но при этом заменив название таблицы gyms на 'g', а название таблицы customers на 'c'. Используй AS для временной замены названий.
undefined
1
Задача
Модуль 4. Работа с БД, 3 уровень, 0 лекция
Недоступна
task0306
Требуется найти колонку location из таблицы gyms, и колонки name и sex из таблицы customers, но при этом заменив название таблицы gyms на 'gym', а название таблицы customers на 'visitor'. Используй AS для временной замены названий.
undefined
1
Задача
Модуль 4. Работа с БД, 3 уровень, 0 лекция
Недоступна
task0307
Требуется найти колонки id и name из таблицы gyms, и колонку id из таблицы customers, но при этом заменив название таблицы gyms на 'gym', а название таблицы customers на 'cust'. Также, нам не нужны все id из таблицы cust, а только те, которые меньше 50. Используй AS и WHERE.
undefined
1
Задача
Модуль 4. Работа с БД, 3 уровень, 0 лекция
Недоступна
task0308
Требуется найти колонку location из таблицы gyms, и колонки name, email и telephone из таблицы customers, но при этом заменив название таблицы gyms на 'g', а название таблицы customers на 'person'. Также, нам нужен person только с именем 'Hulk'. Используй AS и WHERE.
undefined
1
Задача
Модуль 4. Работа с БД, 3 уровень, 0 лекция
Недоступна
task0309
Первым делом требуется выбрать колонки location из таблиц gyms и customers, но заменив при этом название таблицы gyms на 'gym', а название таблицы customers на 'person'. Также, нам нужно исключить из результата location 'London' таблицы person. И в конце концов следует сгрупи