Inserting Query Results

Sometimes the rows you want to add are already in the database, in one form or another. Instead of writing them out after VALUES, you can let a query find them: INSERT INTO … SELECT … adds every row that the query finds.

The shop is preparing Deluxe editions of its RPGs, each $10 more expensive than the original, out on 2026-03-01. Each of them is a copy of an existing game, with a few changes:

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';

The query finds two RPGs, so the INSERT adds two games (Rows changed: 2), with the IDs 21 and 22:

idtitlegenrepricereleased
21Dragon Forge DeluxeRPG502026-03-01
22Knight's Oath DeluxeRPG702026-03-01

The query's columns go into the listed columns by their order, not by their names: the query's first column into the first column of the list, and so on. That's why the query can have title || ' Deluxe' where the table has title, and fixed values such as '2026-03-01', which are the same in every row. The numbers must match: when the query has fewer columns than the list, you get an error such as 3 values for 4 columns.

The query can be anything you know: with WHERE, joins, GROUP BY or subqueries. Write it on its own first, run it and check its result. When it shows exactly the rows you want to add, put the INSERT INTO line above it. It's the same advice as for the WHERE of an UPDATE: look before you change.

Typical mistake: the query's columns in a different order than the list. With (customer_id, ordered_at, status) and SELECT id, 'paid', '2026-01-01', the date would go into the status. Here, the database stops it with CHECK constraint failed: status IN ('paid', 'refunded'), but two text columns without a rule would quietly swap their values.

Instructions

The shop wants to thank its most loyal customers: everyone who has placed at least 3 paid orders gets a gift. Write an INSERT … SELECT that adds a new order for each of them, dated 2026-01-01, with the status paid (the gift goes into the orders later). Find the customers with a query first: group the paid orders by customer and keep those with at least 3.

Below it, show the customer, the date and the status of the orders with an ID greater than 30, sorted by customer. There should be four of them:

customer_idordered_atstatus
12026-01-01paid
22026-01-01paid
32026-01-01paid
42026-01-01paid

The gift is Lost Temple (game 9), one copy for $0. With a second INSERT … SELECT, add it as an item to each of the new orders, which you'll find by their date. Then show all the items of Lost Temple, which nobody had bought before: the name of the customer who got it, the quantity and the price, sorted by name. They should be just the four gifts:

namequantityprice
Emma Clark10
Liam Turner10
Noah Wilson10
Olivia Brown10

Start programming for free

By signing up, you agree to the Terms of Service and Privacy Policy.

Or sign up with:

9/9