diff --git a/02_activities/assignments/assignment2.sql b/02_activities/assignments/assignment2.sql index 5ad40748a..0d93e262d 100644 --- a/02_activities/assignments/assignment2.sql +++ b/02_activities/assignments/assignment2.sql @@ -19,8 +19,14 @@ HINT: keep the syntax the same, but edited the correct components with the strin The `||` values concatenate the columns into strings. Edit the appropriate columns -- you're making two edits -- and the NULL rows will be fixed. All the other rows will remain the same.) */ - - +SELECT + product_name + || ', ' + || COALESCE(product_size, '') + || ' (' + || COALESCE(product_qty_type, 'unit') + || ')' +FROM product; --Windowed Functions /* 1. Write a query that selects from the customer_purchases table and numbers each customer’s @@ -32,18 +38,87 @@ each new market date for each customer, or select only the unique market dates p (without purchase details) and number those visits. HINT: One of these approaches uses ROW_NUMBER() and one uses DENSE_RANK(). */ +--dense_rank +SELECT + customer_id, + market_date, + DENSE_RANK() + OVER ( + PARTITION BY customer_id + ORDER BY market_date + ) AS visit_number +FROM ( + SELECT DISTINCT + customer_id, + market_date + FROM customer_purchases +) AS unique_visits; + +--row_number +SELECT + customer_id, + market_date, + ROW_NUMBER() + OVER ( + PARTITION BY customer_id + ORDER BY market_date + ) AS visit_number +FROM customer_purchases; /* 2. Reverse the numbering of the query from a part so each customer’s most recent visit is labeled 1, then write another query that uses this one as a subquery (or temp table) and filters the results to only the customer’s most recent visit. */ - - +--Reverse-rank +SELECT + customer_id, + market_date, + DENSE_RANK() + OVER ( + PARTITION BY customer_id + ORDER BY market_date DESC + ) AS recent_visit_rank +FROM ( + SELECT DISTINCT + customer_id, + market_date + FROM customer_purchases +) AS unique_visits; + +--filter recent visit +WITH ranked_visits AS ( + SELECT + customer_id, + market_date, + DENSE_RANK() + OVER ( + PARTITION BY customer_id + ORDER BY market_date DESC + ) AS recent_visit_rank + FROM ( + SELECT DISTINCT + customer_id, + market_date + FROM customer_purchases + ) AS unique_visits +) +SELECT + customer_id, + market_date +FROM ranked_visits +WHERE recent_visit_rank = 1; /* 3. Using a COUNT() window function, include a value along with each row of the customer_purchases table that indicates how many different times that customer has purchased that product_id. */ - +SELECT + cp.*, + COUNT(*) + OVER ( + PARTITION BY customer_id, + product_id + ) AS times_purchased +FROM customer_purchases AS cp; -- String manipulations /* 1. Some product names in the product table have descriptions like "Jar" or "Organic". @@ -57,10 +132,27 @@ Remove any trailing or leading whitespaces. Don't just use a case statement for Hint: you might need to use INSTR(product_name,'-') to find the hyphens. INSTR will help split the column. */ +SELECT + product_name, + CASE + WHEN INSTR(product_name, '-') > 0 + THEN TRIM( + SUBSTR( + product_name, + INSTR(product_name, '-') + 1 + ) + ) + ELSE NULL + END AS description +FROM product; /* 2. Filter the query to show any product_size value that contain a number with REGEXP. */ - +SELECT + product_name, + product_size +FROM product +WHERE product_size REGEXP '[0-9]'; -- UNION @@ -73,7 +165,32 @@ HINT: There are a possibly a few ways to do this query, but if you're struggling 3) Query the second temp table twice, once for the best day, once for the worst day, with a UNION binding them. */ - +WITH daily_totals AS ( + SELECT + market_date, + SUM(quantity * cost_to_customer_per_qty) AS total_sales + FROM customer_purchases + GROUP BY market_date +) +SELECT + 'Highest' AS which, + market_date, + total_sales +FROM daily_totals +WHERE total_sales = ( + SELECT MAX(total_sales) + FROM daily_totals +) +UNION +SELECT + 'Lowest' AS which, + market_date, + total_sales +FROM daily_totals +WHERE total_sales = ( + SELECT MIN(total_sales) + FROM daily_totals +); /* SECTION 3 */ @@ -88,7 +205,17 @@ Remember, CROSS JOIN will explode your table rows, so CROSS JOIN should likely b Think a bit about the row counts: how many distinct vendors, product names are there (x)? How many customers are there (y). Before your final group by you should have the product of those two queries (x*y). */ - +SELECT + v.vendor_name, + p.product_name, + SUM(5 * vi.original_price) AS potential_revenue +FROM vendor_inventory AS vi +JOIN vendor AS v ON vi.vendor_id = v.vendor_id +JOIN product AS p ON vi.product_id = p.product_id +CROSS JOIN customer AS c +GROUP BY + v.vendor_name, + p.product_name; -- INSERT @@ -96,20 +223,44 @@ Before your final group by you should have the product of those two queries (x*y This table will contain only products where the `product_qty_type = 'unit'`. It should use all of the columns from the product table, as well as a new column for the `CURRENT_TIMESTAMP`. Name the timestamp column `snapshot_timestamp`. */ - +CREATE TABLE product_units AS +SELECT + *, + CURRENT_TIMESTAMP AS snapshot_timestamp +FROM product +WHERE product_qty_type = 'unit'; /*2. Using `INSERT`, add a new row to the product_units table (with an updated timestamp). This can be any product you desire (e.g. add another record for Apple Pie). */ - +INSERT INTO product_units ( + product_id, + product_name, + product_size, + product_qty_type, + snapshot_timestamp +) +VALUES ( + 999, + 'Apple Pie', + 'Individual', + 'unit', + CURRENT_TIMESTAMP +); -- DELETE /* 1. Delete the older record for the whatever product you added. HINT: If you don't specify a WHERE clause, you are going to have a bad time.*/ - +DELETE FROM product_units +WHERE product_name = 'Apple Pie' + AND snapshot_timestamp < ( + SELECT MAX(snapshot_timestamp) + FROM product_units + WHERE product_name = 'Apple Pie' +); -- UPDATE /* 1.We want to add the current_quantity to the product_units table. @@ -129,5 +280,20 @@ Finally, make sure you have a WHERE statement to update the right row, When you have all of these components, you can run the update statement. */ +ALTER TABLE product_units +ADD current_quantity INT; + + +UPDATE product_units AS pu +SET current_quantity = COALESCE( + ( + SELECT vi.quantity + FROM vendor_inventory AS vi + WHERE vi.product_id = pu.product_id + ORDER BY vi.market_date DESC + LIMIT 1 + ), + 0 +); diff --git a/02_activities/assignments/images/Small bookstore logical prompt 1-Assignment2.PNG b/02_activities/assignments/images/Small bookstore logical prompt 1-Assignment2.PNG new file mode 100644 index 000000000..d83ff310a Binary files /dev/null and b/02_activities/assignments/images/Small bookstore logical prompt 1-Assignment2.PNG differ diff --git a/02_activities/assignments/images/Small bookstore logical prompt 2-Assignment2.PNG b/02_activities/assignments/images/Small bookstore logical prompt 2-Assignment2.PNG new file mode 100644 index 000000000..1ea654acd Binary files /dev/null and b/02_activities/assignments/images/Small bookstore logical prompt 2-Assignment2.PNG differ diff --git a/02_activities/assignments/images/Small bookstore logical prompt 3-Assignment2.PNG b/02_activities/assignments/images/Small bookstore logical prompt 3-Assignment2.PNG new file mode 100644 index 000000000..0d63aa34f Binary files /dev/null and b/02_activities/assignments/images/Small bookstore logical prompt 3-Assignment2.PNG differ