diff --git a/sql/task1.sql b/sql/task1.sql index 90de336ca..785a2a00b 100644 --- a/sql/task1.sql +++ b/sql/task1.sql @@ -1,14 +1,54 @@ -- Problem 1: Retrieve all products in the Sports category -- Write an SQL query to retrieve all products in a specific category. +-- Load data from files .csv files: + +SELECT + product_id, product_name +FROM + products +WHERE + category_id = 8; -- The category id for sports is 8, hence I ran the query by category ID. You can also query by category name if you use JOIN. + -- 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 + users.user_id, users.username, COUNT(order_id) AS total_orders +FROM + orders +JOIN + users ON orders.user_id = users.user_id +GROUP BY + users.user_id, users.username; -- This retrieves the total number of ORDERS, not the total amount of items ordered. + -- 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. +SELECT + products.product_id, products.product_name, AVG(rating) AS average_rating +FROM + reviews +JOIN + products ON products.product_id = reviews.product_id -- Ensures that we get the average for each product +GROUP BY + products.product_id; + + -- 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 + users.user_id, username, SUM(total_amount) AS total_spent +FROM + users, orders +WHERE + users.user_id = orders.user_id +GROUP BY + users.user_id +ORDER BY + total_spent DESC +LIMIT 5; -- Only retrieve the top 5 users diff --git a/sql/task2.sql b/sql/task2.sql index ad2596731..fd2fb204f 100644 --- a/sql/task2.sql +++ b/sql/task2.sql @@ -3,17 +3,92 @@ -- 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. +WITH AvgRating AS ( + SELECT + products.product_id, + products.product_name, + AVG(rating) AS product_average_rating + FROM + reviews + JOIN + products ON products.product_id = reviews.product_id + GROUP BY + products.product_id +) -- This block of code creates the CTE + +SELECT + product_id, + product_name, + product_average_rating +FROM + AvgRating +WHERE + product_average_rating = (SELECT MAX(product_average_rating) FROM AvgRating); -- get the max value from AvgRating CTE + -- 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 + username +FROM + users +WHERE ( + SELECT + COUNT(DISTINCT category_id) + FROM + orders + JOIN + order_items ON order_items.order_id = orders.order_id + JOIN + products ON order_items.product_id = products.product_id + WHERE orders.user_id = users.user_id + ) = + + (SELECT + COUNT(DISTINCT category_id) -- check if the user has made at least one order in each category + FROM + categories); + + -- There are no users that have made at least one order in each category! + -- 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 + product_id, product_name +FROM + products +WHERE + product_id NOT IN ( + SELECT + product_id + FROM + reviews + ); -- Used a subquery to retrieve the products without reviews + +-- There are no products without reviews! + -- 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. + +SELECT DISTINCT + ub.user_id, + ub.username +FROM ( + SELECT + u.user_id, + u.username, + datediff(o.order_date, LAG(o.order_date, 1) OVER (PARTITION BY u.user_id ORDER BY o.order_date)) AS difference + FROM + users u, orders o + WHERE + u.user_id = o.user_id +) ub +WHERE + ub.difference is not null and ub.difference = 1 -- return if it was a consecutive day \ No newline at end of file diff --git a/sql/task3.sql b/sql/task3.sql index f078a9439..43df54d89 100644 --- a/sql/task3.sql +++ b/sql/task3.sql @@ -3,17 +3,101 @@ -- 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 + categories.category_id, category_name, SUM(quantity * unit_price) AS total_amount +FROM + categories +JOIN + products ON categories.category_id = products.category_id +JOIN + order_items ON products.product_id = order_items.product_id +GROUP BY + categories.category_id +ORDER BY + total_amount 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. +SELECT + user_id, + username +FROM + users +WHERE ( + SELECT COUNT(DISTINCT order_items.product_id) + FROM + order_items + JOIN + orders ON orders.order_id = order_items.order_id + JOIN + products ON products.product_id = order_items.product_id + JOIN + categories ON products.category_id = categories.category_id + WHERE orders.user_id = users.user_id and category_name = 'Toys & Games') + = + (SELECT COUNT(Distinct product_id) + FROM + products + JOIN + categories ON categories.category_id = products.category_id + WHERE + category_name = 'Toys & Games'); + + -- Sarah placed the most orders for Toys & Games + -- 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. + +WITH MaxP AS ( + SELECT + category_id, MAX(price) as highest_price + FROM + products + GROUP BY + category_id +) + +SELECT + product_id, + product_name, + products.category_id, + highest_price +FROM + products +JOIN + MaxP ON products.category_id = MaxP.category_id +WHERE + price = highest_price; + -- 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. +-- Hint: You may need to use subqueries, joins, and window functions to solve this problem + +WITH OrderDateRank AS ( + SELECT + ordered.user_id, + ordered.order_date, + RANK() OVER (PARTITION BY ordered.user_id ORDER BY ordered.order_date) AS ranked + FROM Orders ordered +) + +SELECT + users.user_id, + users.username +FROM + OrderDateRank ordered +INNER JOIN + Users users ON ordered.user_id = users.user_id +WHERE + ordered.ranked >= 3; + + -- There are no users who retrieved orders on consecutive days \ No newline at end of file diff --git a/tests/test_sql_queries.py b/tests/test_sql_queries.py index 22b25d546..6e45799d0 100644 --- a/tests/test_sql_queries.py +++ b/tests/test_sql_queries.py @@ -6,11 +6,11 @@ class TestSQLQueries(unittest.TestCase): def setUp(self): # Establish a connection to your test database self.conn = psycopg2.connect( - dbname='your_dbname', - user='your_username', - password='your_password', - host='your_host', - port='your_port' + dbname='test_db', + user='alinco', + password='123', + host='localhost', + port='3306' ) self.cur = self.conn.cursor() @@ -52,4 +52,4 @@ def test_task2(self): # Add more test methods for additional SQL tasks if __name__ == '__main__': - unittest.main() \ No newline at end of file + unittest.main()