From 809c8039eb19d7c91f246ec108a9737a21f09c5d Mon Sep 17 00:00:00 2001 From: qianyineonli <153569689+qianyineonli@users.noreply.github.com> Date: Mon, 29 Jan 2024 23:15:17 -0500 Subject: [PATCH] submission --- sql/task1.sql | 22 +++++++++++++++++ sql/task2.sql | 39 ++++++++++++++++++++++++++++++- sql/task3.sql | 65 +++++++++++++++++++++++++++++++++++++++++++++++++++ 3 files changed, 125 insertions(+), 1 deletion(-) diff --git a/sql/task1.sql b/sql/task1.sql index 90de336ca..2d0d2ae91 100644 --- a/sql/task1.sql +++ b/sql/task1.sql @@ -1,14 +1,36 @@ -- Problem 1: Retrieve all products in the Sports category -- Write an SQL query to retrieve all products in a specific category. +SELECT p.*, c.category_name +FROM Products AS p LEFT JOIN Categories AS c ON p.category_id = c.category_id +WHERE c.category_name = 'Sports & Outdoors'; -- Problem 2: Retrieve the total number of orders for each user -- Write an SQL query to retrieve the total number of orders for each user. -- The result should include the user ID, username, and the total number of orders. +SELECT u.user_id, + u.username, + count(distinct order_id) as total_num_of_orders +FROM Users AS u LEFT JOIN Orders AS o ON u.user_id = o.user_id +GROUP BY u.user_id, u.username; -- Problem 3: Retrieve the average rating for each product -- Write an SQL query to retrieve the average rating for each product. -- The result should include the product ID, product name, and the average rating. +# Exclude Review for Products Not in the Product Table as Products Table generally defines the set +# of valid produc +SELECT p.product_id, p.product_name, AVG(rating) AS average_rating +FROM Products AS p LEFT JOIN Reviews AS r ON p.product_id = r.product_id +GROUP BY p.product_id, p.product_name; + -- Problem 4: Retrieve the top 5 users with the highest total amount spent on orders -- Write an SQL query to retrieve the top 5 users with the highest total amount spent on orders. -- The result should include the user ID, username, and the total amount spent. +SELECT u.user_id, u.username, SUM(total_amount) as total_amount_spent +FROM Users AS u LEFT JOIN Orders as o ON u.user_id = o.order_id +GROUP BY u.user_id, u.username +ORDER BY SUM(total_amount) DESC +LIMIT 5; + + + diff --git a/sql/task2.sql b/sql/task2.sql index ad2596731..66ebd3904 100644 --- a/sql/task2.sql +++ b/sql/task2.sql @@ -3,17 +3,54 @@ -- The result should include the product ID, product name, and the average rating. -- Hint: You may need to use subqueries or common table expressions (CTEs) to solve this problem. +SELECT p.product_id, p.product_name, AVG(rating) as average_rating +FROM Products as p LEFT JOIN Reviews as r ON p.product_id = r.product_id +GROUP BY p.product_id, p.product_name +HAVING AVG(rating) = +#Find the highest average rating +(SELECT MAX(average_rating) +FROM ( +SELECT p.product_id, p.product_name, AVG(rating) as average_rating +FROM Products as p LEFT JOIN Reviews as r ON p.product_id = r.product_id +GROUP BY p.product_id, p.product_name ) AS p1) ; + -- Problem 6: Retrieve the users who have made at least one order in each category -- Write an SQL query to retrieve the users who have made at least one order in each category. -- The result should include the user ID and username. -- Hint: You may need to use subqueries or joins to solve this problem. +SELECT u.user_id, u.username, COUNT(DISTINCT p.category_id) as category_count +FROM Users as u LEFT JOIN Orders AS o on u.user_id = o.user_id + LEFT JOIN Order_Items as i on o.order_id = i.order_id + LEFT JOIN Products as p on i.product_id = p.product_id +GROUP BY u.user_id, u.username +HAVING COUNT(DISTINCT p.category_id) = +(#retrive all the possible category_id from the Categories table +SELECT COUNT(DISTINCT category_id) +FROM Categories); + -- Problem 7: Retrieve the products that have not received any reviews -- Write an SQL query to retrieve the products that have not received any reviews. -- The result should include the product ID and product name. -- Hint: You may need to use subqueries or left joins to solve this problem. +SELECT p.product_id, p.product_name, COUNT(review_id) AS num_review +FROM Products AS p LEFT JOIN Reviews AS r on p.product_id = r.product_id +GROUP BY p.product_id, p.product_name +HAVING COUNT(review_id) = 0; + -- Problem 8: Retrieve the users who have made consecutive orders on consecutive days -- Write an SQL query to retrieve the users who have made consecutive orders on consecutive days. -- The result should include the user ID and username. --- Hint: You may need to use subqueries or window functions to solve this problem. \ No newline at end of file +-- Hint: You may need to use subqueries or window functions to solve this problem. + +#Find the previous order date for each order +With ConsecutiveOrder AS ( +SELECT u.user_id, u.username, o.order_date, LAG(o.order_date) OVER (PARTITION BY u.user_id ORDER BY o.order_date) as previous_order_date +FROM Users AS u LEFT JOIN Orders AS O ON u.user_id = o.user_id) + +#If the date difference between the order date and the previous order date is equal to 1 +# we consider ths user have made orders in consecutive date +SELECT DISTINCT user_id, username +FROM ConsecutiveOrder +WHERE DATEDIFF(order_date, previous_order_date) = 1; \ No newline at end of file diff --git a/sql/task3.sql b/sql/task3.sql index f078a9439..11d1adf65 100644 --- a/sql/task3.sql +++ b/sql/task3.sql @@ -3,17 +3,82 @@ -- The result should include the category ID, category name, and the total sales amount. -- Hint: You may need to use subqueries, joins, and aggregate functions to solve this problem. +SELECT c.category_id, c.category_name, SUM(quantity* unit_price) AS total_sales_amount +FROM Categories AS c LEFT JOIN Products AS p ON c.category_id = p.category_id + LEFT JOIN Order_Items AS i ON p.product_id = i.product_id +GROUP BY c.category_id, c.category_name +ORDER BY SUM(quantity* unit_price) DESC +LIMIT 3; + -- Problem 10: Retrieve the users who have placed orders for all products in the Toys & Games -- Write an SQL query to retrieve the users who have placed orders for all products in the Toys & Games -- The result should include the user ID and username. -- Hint: You may need to use subqueries, joins, and aggregate functions to solve this problem. +#Find the category_id for 'Toys & Games' +WITH ToyCategory AS ( +SELECT category_id +FROM Categories +WHERE category_name = 'Toys & Games'), + +#Find all product_id in that category +ToyProductIDs AS ( +SELECT DISTINCT product_id +FROM Products +WHERE category_id = (SELECT * FROM ToyCategory)), + +#Find all orders +AllOrders AS( +SELECT u.user_id, u.username, i.product_id +FROM Users as u JOIN Orders AS o ON u.user_id = o.user_id + JOIN Order_Items AS i ON o.order_id = i.order_id + JOIN Products AS p on p.product_id = i.product_id) + +#Find all the users who have placed orders for all products in the Toys & Games +SELECT user_id, username +FROM ALLOrders +GROUP BY user_id, username +HAVING COUNT(DISTINCT product_id) = (SELECT COUNT(*) FROM ToyProductIDs); + + -- Problem 11: Retrieve the products that have the highest price within each category -- Write an SQL query to retrieve the products that have the highest price within each category. -- The result should include the product ID, product name, category ID, and price. -- Hint: You may need to use subqueries, joins, and window functions to solve this problem. +SELECT product_id, product_name, category_id, price +FROM ( +#Rank product price in a dese order for each category +SELECT product_id, product_name, category_id, price, + RANK() OVER (PARTITION BY category_id ORDER BY price DESC) as price_rank +FROM Products) AS p1 +WHERE price_rank =1 ; + -- Problem 12: Retrieve the users who have placed orders on consecutive days for at least 3 days -- Write an SQL query to retrieve the users who have placed orders on consecutive days for at least 3 days. -- The result should include the user ID and username. -- Hint: You may need to use subqueries, joins, and window functions to solve this problem. + +# Gather order date, keep unique order_date for each user_id +WITH uniqueOrderDate as( +SELECT user_id, order_date +FROM Orders +GROUP BY user_id, order_date), + +# For consecutive dates, the value of grp will be the same because for all consecutive dates +consecutiveGroup as ( +SELECT *, ROW_NUMBER() OVER (PARTITION BY user_id ORDER BY order_date) AS row_num, +DATE_SUB(order_date, INTERVAL ROW_NUMBER() OVER (PARTITION BY user_id ORDER BY order_date) DAY) as grp +FROM uniqueOrderDate), + +# Select the user_id who have placed orders on consecutive days for at least 3 days +userIdList AS ( +SELECT user_id, COUNT(*) AS consecutiveDates +FROM consecutiveGroup +GROUP BY user_id, grp +HAVING COUNT(*) >=3) + +#Get the distinct user_id and join Users table for user_name information +SELECT DISTINCT l.user_id as user_id, u.username +FROM userIdList AS l LEFT JOIN Users AS u ON l.user_id = u.user_id; +