Вставка результатов запроса
Иногда строки, которые вы хотите добавить, уже есть в базе данных в том или ином виде. Вместо того чтобы выписывать их после VALUES, можно поручить поиск запросу: INSERT INTO … SELECT … добавляет каждую строку, которую находит запрос.
Магазин готовит Deluxe-издания своих RPG, каждое на $10 дороже оригинала и с датой выхода 2026-03-01. Каждое из них — копия существующей игры с несколькими изменениями:
INSERT INTO games (title, genre, price, released, age_rating)
SELECT title || ' Deluxe', genre, price + 10, '2026-03-01', age_rating
FROM games
WHERE genre = 'RPG';Запрос находит две RPG, поэтому INSERT добавляет две игры (Изменено строк: 2) с ID 21 и 22:
| id | title | genre | price | released |
|---|---|---|---|---|
| 21 | Dragon Forge Deluxe | RPG | 50 | 2026-03-01 |
| 22 | Knight's Oath Deluxe | RPG | 70 | 2026-03-01 |
Столбцы запроса попадают в перечисленные столбцы по порядку, а не по именам: первый столбец запроса — в первый столбец списка и так далее. Поэтому в запросе может быть title || ' Deluxe' там, где в таблице title, и постоянные значения вроде '2026-03-01', одинаковые в каждой строке. Количество столбцов должно совпадать: если в запросе их меньше, чем в списке, вы получите ошибку вроде 3 values for 4 columns.
Запрос может быть любым из тех, что вы знаете: с WHERE, соединениями, GROUP BY или подзапросами. Сначала напишите его отдельно, запустите и проверьте результат. Когда он показывает ровно те строки, которые нужно добавить, поставьте над ним строку INSERT INTO. Это тот же совет, что и про WHERE в UPDATE: сначала посмотрите, потом меняйте.
Типичная ошибка: столбцы запроса идут в другом порядке, чем в списке. При (customer_id, ordered_at, status) и SELECT id, 'paid', '2026-01-01' дата попала бы в статус. Здесь база данных остановит это ошибкой CHECK constraint failed: status IN ('paid', 'refunded'), но два текстовых столбца без правила тихо поменялись бы значениями.
Задание
- 1
Магазин хочет поблагодарить самых преданных клиентов: каждый, у кого не меньше 3 оплаченных заказов, получает подарок. Напишите
INSERT … SELECT, который добавит для каждого из них новый заказ с датой 2026-01-01 и статусомpaid(сам подарок позже попадёт в состав заказа). Сначала найдите клиентов запросом: сгруппируйте оплаченные заказы по клиентам и оставьте тех, у кого их не меньше 3. - 2
Ниже покажите клиента, дату и статус заказов с ID больше 30, отсортировав их по клиенту. Их должно быть четыре:
customer_id ordered_at status 1 2026-01-01 paid 2 2026-01-01 paid 3 2026-01-01 paid 4 2026-01-01 paid - 3
Подарок — Lost Temple (игра 9), один экземпляр за $0. Вторым
INSERT … SELECTдобавьте его как позицию в каждый из новых заказов, которые вы найдёте по дате. Затем покажите все позиции Lost Temple, которую раньше никто не покупал: имя клиента, получившего её, количество и цену, отсортировав их по имени. Это должны быть только четыре подарка:name quantity price Emma Clark 1 0 Liam Turner 1 0 Noah Wilson 1 0 Olivia Brown 1 0