Generate the Invoice
Problem
Table: Products
+-------------+------+
| Column Name | Type |
+-------------+------+
| product_id | int |
| price | int |
+-------------+------+
product_id contains unique values.
Each row in this table shows the ID of a product and the price of one unit.
Table: Purchases
+-------------+------+
| Column Name | Type |
+-------------+------+
| invoice_id | int |
| product_id | int |
| quantity | int |
+-------------+------+
(invoice_id, product_id) is the primary key (combination of columns with unique values) for this table.
Each row in this table shows the quantity ordered from one product in an invoice.
Problem Definition
Write a solution to show the details of the invoice with the highest price. If two or more invoices have the same price, return the details of the one with the smallest invoice_id.
Return the result table in any order.
Example
Output
Try It Yourself
-- TODO: Write your user queries here
Solution
To identify the invoice with the highest total price, and in the event of a tie, select the one with the smallest invoice_id, we can follow a systematic approach using SQL's aggregation and window functions. The solution involves calculating the total price for each invoice, determining the highest total price, handling ties by selecting the smallest invoice_id, and finally retrieving the detailed information of the selected invoice.
Approach Overview
-
Join
PurchaseswithProductsto Calculate Subtotal per Product:- Combine the
PurchasesandProductstables to access the price of each product. - Calculate the subtotal for each product in an invoice by multiplying
pricebyquantity.
- Combine the
-
Aggregate Subtotals to Determine Total Price per Invoice:
- Sum the subtotals for each
invoice_idto obtain the total price of each invoice.
- Sum the subtotals for each
-
Identify the Invoice with the Highest Total Price:
- Determine the maximum total price across all invoices.
- In cases where multiple invoices share this maximum total price, select the one with the smallest
invoice_id.
-
Retrieve Detailed Information of the Selected Invoice:
- Fetch the
product_id,quantity, and subtotal (price) for each product within the selected invoice.
- Fetch the
SQL Query
WITH details_by_invoices AS ( SELECT pu.invoice_id, pu.product_id, pu.quantity, pu.quantity * pr.price AS price FROM Purchases AS pu INNER JOIN Products AS pr ON pu.product_id = pr.product_id ), invoice_with_max_total AS ( SELECT invoice_id FROM details_by_invoices GROUP BY invoice_id ORDER BY SUM(price) DESC, invoice_id ASC LIMIT 1 ) SELECT product_id, quantity, price FROM details_by_invoices WHERE invoice_id IN ( SELECT invoice_id FROM invoice_with_max_total );
Step-by-Step Approach
Step 1: Join Purchases with Products and Calculate Subtotal per Product (details_by_invoices)
Combine the Purchases and Products tables to calculate the subtotal for each product within an invoice.
SQL Snippet:
WITH details_by_invoices AS ( SELECT pu.invoice_id, pu.product_id, pu.quantity, pu.quantity * pr.price AS price FROM Purchases AS pu INNER JOIN Products AS pr ON pu.product_id = pr.product_id ) SELECT * FROM details_by_invoices;
Explanation:
INNER JOIN:- Combines each purchase (
pu) with its corresponding product (pr) based onproduct_id.
- Combines each purchase (
- Calculate Subtotal (
price):- Multiplies
quantitybypriceto compute the subtotal for each product in an invoice.
- Multiplies
- Common Table Expression (CTE)
details_by_invoices:- Stores the resulting data for further processing.
Intermediate Output After Step 1 (details_by_invoices):
+------------+------------+----------+-------+ | invoice_id | product_id | quantity | price | +------------+------------+----------+-------+ | 1 | 1 | 2 | 200 | | 3 | 2 | 1 | 200 | | 2 | 2 | 3 | 600 | | 2 | 1 | 4 | 400 | | 4 | 1 | 10 | 1000 | +------------+------------+----------+-------+
Step 2: Aggregate Subtotals to Determine Total Price per Invoice
Calculate the total price for each invoice by summing the subtotals of all products within that invoice.
SQL Snippet:
WITH details_by_invoices AS ( SELECT pu.invoice_id, pu.product_id, pu.quantity, pu.quantity * pr.price AS price FROM Purchases AS pu INNER JOIN Products AS pr ON pu.product_id = pr.product_id ), invoice_with_max_total AS ( SELECT invoice_id FROM details_by_invoices GROUP BY invoice_id )
Explanation:
GROUP BY invoice_id:- Aggregates all products within the same invoice.
SUM(price) AS total_price:- Calculates the total price for each invoice by summing the subtotals of its products.
- Common Table Expression (CTE)
invoice_with_max_total:- Identifies the invoice with the highest total price, handling ties by selecting the smallest
invoice_id.
- Identifies the invoice with the highest total price, handling ties by selecting the smallest
Intermediate Output After Step 2:
+------------+-------------+ | invoice_id | total_price | +------------+-------------+ | 1 | 200 | | 2 | 1000 | | 3 | 200 | | 4 | 1000 | +------------+-------------+
Step 3: Identify the Invoice with the Highest Total Price (invoice_with_max_total)
Determine which invoice has the highest total_price. In the case of a tie, select the invoice with the smallest invoice_id.
SQL Snippet:
WITH details_by_invoices AS ( SELECT pu.invoice_id, pu.product_id, pu.quantity, pu.quantity * pr.price AS price FROM Purchases AS pu INNER JOIN Products AS pr ON pu.product_id = pr.product_id ), invoice_with_max_total AS ( SELECT invoice_id FROM details_by_invoices GROUP BY invoice_id ORDER BY SUM(price) DESC, invoice_id ASC LIMIT 1 ) SELECT * FROM invoice_with_max_total;
Explanation:
ORDER BY SUM(price) DESC, invoice_id ASC:- Sorts the invoices first by descending
total_priceto prioritize higher totals. - In case of a tie in
total_price, sorts by ascendinginvoice_idto select the smallest ID.
- Sorts the invoices first by descending
LIMIT 1:- Ensures that only the top invoice is selected based on the sorting criteria.
Intermediate Output After Step 3 (invoice_with_max_total):
+------------+ | invoice_id | +------------+ | 2 | +------------+
Step 4: Retrieve Detailed Information of the Selected Invoice
Fetch the product_id, quantity, and subtotal (price) for each product within the selected invoice.
SQL Snippet:
WITH details_by_invoices AS ( SELECT pu.invoice_id, pu.product_id, pu.quantity, pu.quantity * pr.price AS price FROM Purchases AS pu INNER JOIN Products AS pr ON pu.product_id = pr.product_id ), invoice_with_max_total AS ( SELECT invoice_id FROM details_by_invoices GROUP BY invoice_id ORDER BY SUM(price) DESC, invoice_id ASC LIMIT 1 ) SELECT product_id, quantity, price FROM details_by_invoices WHERE invoice_id IN ( SELECT invoice_id FROM invoice_with_max_total ) ORDER BY product_id;
Explanation:
WHERE invoice_id IN (SELECT invoice_id FROM invoice_with_max_total):- Filters the
details_by_invoicesto include only the selected invoice.
- Filters the
ORDER BY product_id:- Sorts the output by
product_idfor organized presentation.
- Sorts the output by
Final Output:
+------------+----------+-------+ | product_id | quantity | price | +------------+----------+-------+ | 1 | 4 | 400 | | 2 | 3 | 600 | +------------+----------+-------+
Explanation of Output:
-
Product 1:
- Quantity: 4
- Price per unit: $100
- Subtotal: 4 × $100 = $400
-
Product 2:
- Quantity: 3
- Price per unit: $200
- Subtotal: 3 × $200 = $600
-
Total for Invoice 2: $400 + $600 = $1000
Note:
- Invoice 4 also has a
total_priceof $1000, but Invoice 2 is selected because it has the smallerinvoice_id.
🤖 Don't fully get this? Learn it with Claude
Stuck on Generate the Invoice? Open Claude, copy a block below, and it'll teach you this exact concept — visually and interactively.
Build the mental picture, not memorization.
I just read a lesson on **Generate the Invoice** (Databases) and want to truly understand it. Explain Generate the Invoice from first principles using ONE vivid real-world analogy and a visual mental model — draw it as ASCII art or a clear step-by-step diagram — with a concrete example using real numbers. Then ask me one question to check I got the mental picture, and wait for my reply. If you're unsure or a claim isn't standard, say so and reason from first principles instead of guessing.
Socratic — adapts to where you're stuck.
Teach me **Generate the Invoice** interactively. Ask me ONE guiding question at a time, wait for my answer, and adapt to my confusion — build the idea with me step by step instead of explaining it all at once. If you're unsure or a claim isn't standard, say so and reason from first principles instead of guessing.
Active recall exposes what you missed.
Quiz me on **Generate the Invoice** with 5 questions, easy to tricky, ONE at a time. Tell me if each answer is right; at the end, explain clearly what I got wrong and why. If you're unsure or a claim isn't standard, say so and reason from first principles instead of guessing.
Intuition + hook + flashcards for long-term memory.
Help me remember **Generate the Invoice** for the long term: give the one-sentence intuition, a memorable hook/mnemonic, a tiny worked example, and 3 active-recall flashcards (Q -> A). If you're unsure or a claim isn't standard, say so and reason from first principles instead of guessing.