diff --git a/02_activities/assignments/Assignment 2 Section 1.pdf b/02_activities/assignments/Assignment 2 Section 1.pdf new file mode 100644 index 000000000..386edc99a Binary files /dev/null and b/02_activities/assignments/Assignment 2 Section 1.pdf differ diff --git a/02_activities/assignments/assignment2.sql b/02_activities/assignments/assignment2.sql index 5ad40748a..ae8b14e5a 100644 --- a/02_activities/assignments/assignment2.sql +++ b/02_activities/assignments/assignment2.sql @@ -20,7 +20,11 @@ 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 + COALESCE(product_name, '') || ', ' || + COALESCE(product_size, '') || ' (' || + COALESCE(product_qty_type, 'unit') || ')' AS product_description +FROM product; --Windowed Functions /* 1. Write a query that selects from the customer_purchases table and numbers each customer’s @@ -32,18 +36,47 @@ 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(). */ - +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 visits /* 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. */ - +SELECT * +FROM ( + SELECT + customer_id, + market_date, + DENSE_RANK() OVER ( + PARTITION BY customer_id + ORDER BY market_date DESC + ) AS visit_number + FROM ( + SELECT DISTINCT customer_id, market_date + FROM customer_purchases + ) AS visits +) AS ranked_visits +WHERE visit_number = 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 +customer_id, +product_id, +count(*) OVER(PARTITION BY customer_id, product_id + ) AS customer_product_count +FROM customer_purchases -- String manipulations /* 1. Some product names in the product table have descriptions like "Jar" or "Organic". @@ -57,11 +90,21 @@ 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 * +FROM product +WHERE product_size REGEXP '[0-9]' -- UNION /* 1. Using a UNION, write a query that displays the market dates with the highest and lowest total sales. @@ -73,7 +116,36 @@ 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_sales AS ( + SELECT + market_date, + SUM(quantity * cost_to_customer_per_qty) AS total_sales + FROM customer_purchases + GROUP BY market_date +), +ranked_sales AS ( + SELECT + market_date, + total_sales, + RANK() OVER (ORDER BY total_sales DESC) AS best_day_rank, + RANK() OVER (ORDER BY total_sales ASC) AS worst_day_rank + FROM daily_sales +) +SELECT + market_date, + total_sales, + 'Best Day' AS label +FROM ranked_sales +WHERE best_day_rank = 1 +UNION + +SELECT + market_date, + total_sales, + 'Worst Day' AS label +FROM ranked_sales +WHERE worst_day_rank = 1; /* SECTION 3 */ @@ -89,6 +161,35 @@ Think a bit about the row counts: how many distinct vendors, product names are t How many customers are there (y). Before your final group by you should have the product of those two queries (x*y). */ +WITH vendor_products AS ( + SELECT DISTINCT + v.vendor_id, + v.product_id, + v.original_price, + vendor_name, + product_name + FROM vendor_inventory v + JOIN vendor USING (vendor_id) + JOIN product USING (product_id) +), +customers AS ( + SELECT customer_id FROM customer +), +sales_5 AS ( + SELECT + vp.vendor_name, + vp.product_name, + 5 * vp.original_price AS revenue_per_customer + FROM vendor_products vp + CROSS JOIN customers +) +SELECT + vendor_name, + product_name, + SUM(revenue_per_customer) AS total_revenue +FROM sales_5 +GROUP BY vendor_name, product_name +ORDER BY vendor_name, product_name -- INSERT @@ -102,14 +203,33 @@ Name the timestamp column `snapshot_timestamp`. */ /*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). */ +CREATE TABLE product_units AS +SELECT + *, + CURRENT_TIMESTAMP AS snapshot_timestamp +FROM product +WHERE product_qty_type = 'unit'; + +SELECT* +FROM product_units; +INSERT INTO product_units (product_id, product_name, product_size, product_category_id, product_qty_type, snapshot_timestamp) +VALUES (24, 'Coffee', '500g', 3, 'unit', CURRENT_TIMESTAMP); + +SELECT* +FROM product_units; -- 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 = 'Coffee' + AND snapshot_timestamp = ( + SELECT MIN(snapshot_timestamp) + FROM product_units + WHERE product_name = 'Coffee') -- UPDATE /* 1.We want to add the current_quantity to the product_units table. @@ -127,7 +247,22 @@ Third, SET current_quantity = (...your select statement...), remembering that WH Finally, make sure you have a WHERE statement to update the right row, you'll need to use product_units.product_id to refer to the correct row within the product_units table. When you have all of these components, you can run the update statement. */ +ALTER TABLE product_units +ADD current_quantity INT; + +UPDATE product_units pu +SET current_quantity = ( + SELECT + COALESCE(vi.quantity, 0) + FROM vendor_inventory vi + WHERE vi.product_id = pu.product_id + AND vi.market_date = ( + SELECT MAX(market_date) + FROM vendor_inventory + WHERE product_id = pu.product_id) + LIMIT 1) +--Natalia Rodriguez