Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
21 changes: 21 additions & 0 deletions sql/task1.sql
Original file line number Diff line number Diff line change
@@ -1,14 +1,35 @@
-- Problem 1: Retrieve all products in the Sports category
-- Write an SQL query to retrieve all products in a specific category.
SELECT P.product_id, P.product_name, P.description, P.price, P.category_id
FROM Products P
JOIN Categories C ON P.category_id = C.category_id
WHERE C.category_name LIKE '%Sports%';

-- 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(O.order_id) AS total_orders
FROM Users U
LEFT JOIN Orders O ON U.user_id = O.user_id
GROUP BY U.user_id, U.username
ORDER BY U.user_id;

-- 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 P.product_id, P.product_name, AVG(R.rating) AS average_rating
FROM Products P
LEFT JOIN Reviews R ON P.product_id = R.product_id
GROUP BY P.product_id, P.product_name
ORDER BY P.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 U.user_id, U.username, SUM(O.total_amount) AS total_spent
FROM Users U
JOIN Orders O ON U.user_id = O.user_id
GROUP BY U.user_id, U.username
ORDER BY total_spent DESC
LIMIT 5;
62 changes: 61 additions & 1 deletion sql/task2.sql
Original file line number Diff line number Diff line change
Expand Up @@ -3,17 +3,77 @@
-- 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.

DROP VIEW IF EXISTS ProductAverageRatings CASCADE;
CREATE VIEW ProductAverageRatings AS
SELECT product_id, AVG(rating) AS average_rating
FROM Reviews
GROUP BY product_id;

SELECT P.product_id, P.product_name, PAR.average_rating
FROM Products P
JOIN ProductAverageRatings PAR ON P.product_id = PAR.product_id
WHERE PAR.average_rating = (SELECT MAX(average_rating) FROM ProductAverageRatings);


-- 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.
DROP VIEW IF EXISTS UserCategories CASCADE;
DROP VIEW IF EXISTS UniqueCategories CASCADE;
CREATE VIEW UniqueCategories AS
SELECT DISTINCT category_id
FROM Categories;

CREATE VIEW UserCategories AS
SELECT DISTINCT U.user_id, P.category_id
FROM Users U
JOIN Orders O ON U.user_id = O.user_id
JOIN Order_Items OI ON O.order_id = OI.order_id
JOIN Products P ON OI.product_id = P.product_id;

SELECT U.user_id, U.username
FROM Users U
WHERE NOT EXISTS (
SELECT 1
FROM UniqueCategories UC
WHERE NOT EXISTS (
SELECT 1
FROM UserCategories UC2
WHERE UC2.user_id = U.user_id AND UC2.category_id = UC.category_id
)
)
GROUP BY U.user_id, U.username;


-- 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
FROM Products P
LEFT JOIN Reviews R ON P.product_id = R.product_id
WHERE R.review_id IS NULL;

-- 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.
-- Hint: You may need to use subqueries or window functions to solve this problem.

DROP VIEW IF EXISTS UserOrderDates CASCADE;
DROP VIEW IF EXISTS ConsecutiveUserOrders CASCADE;

CREATE VIEW UserOrderDates AS
SELECT
user_id,
order_date,
LAG(order_date) OVER (PARTITION BY user_id ORDER BY order_date) AS previous_order_date
FROM Orders;
CREATE VIEW ConsecutiveUserOrders AS
SELECT
user_id
FROM UserOrderDates
WHERE order_date - previous_order_date = 1;
SELECT DISTINCT U.user_id, U.username
FROM Users U
JOIN ConsecutiveUserOrders CUO ON U.user_id = CUO.user_id;
85 changes: 85 additions & 0 deletions sql/task3.sql
Original file line number Diff line number Diff line change
Expand Up @@ -3,17 +3,102 @@
-- 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(OI.quantity * OI.unit_price) AS total_sales_amount
FROM
Categories C
JOIN Products P ON C.category_id = P.category_id
JOIN Order_Items OI ON P.product_id = OI.product_id
GROUP BY
C.category_id,
C.category_name
ORDER BY
total_sales_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 U.user_id, U.username
FROM Users U
JOIN Orders O ON U.user_id = O.user_id
JOIN Order_Items OI ON O.order_id = OI.order_id
JOIN Products P ON OI.product_id = P.product_id
JOIN Categories C ON P.category_id = C.category_id
WHERE C.category_name = 'Toys & Games'
GROUP BY U.user_id, U.username
HAVING COUNT(DISTINCT P.product_id) = (
SELECT COUNT(DISTINCT product_id)
FROM Products P
JOIN Categories C ON P.category_id = C.category_id
WHERE C.category_name = '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.
DROP VIEW IF EXISTS HighestPricedProducts CASCADE;
CREATE VIEW HighestPricedProducts AS
WITH RankedProducts AS (
SELECT
product_id,
product_name,
category_id,
price,
RANK() OVER (PARTITION BY category_id ORDER BY price DESC) AS price_rank
FROM Products
)
SELECT
product_id,
product_name,
category_id,
price
FROM RankedProducts
WHERE price_rank = 1;
SELECT * FROM HighestPricedProducts;

-- 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.
DROP VIEW IF EXISTS UserConsecutiveOrders CASCADE;
DROP VIEW IF EXISTS UserConsecutiveStreaks CASCADE;
DROP VIEW IF EXISTS UserStreakLengths CASCADE;
DROP VIEW IF EXISTS UsersWith3DayStreaks CASCADE;
CREATE VIEW UserConsecutiveOrders AS
SELECT
user_id,
order_date,
LAG(order_date) OVER (PARTITION BY user_id ORDER BY order_date) AS previous_order_date
FROM Orders;
CREATE VIEW UserConsecutiveStreaks AS
SELECT
user_id,
order_date,
CASE
WHEN order_date - previous_order_date = 1 THEN 0
ELSE 1
END AS streak_start
FROM UserConsecutiveOrders;
CREATE VIEW UserStreakLengths AS
SELECT
user_id,
order_date,
SUM(streak_start) OVER (PARTITION BY user_id ORDER BY order_date) AS streak_id
FROM UserConsecutiveStreaks;
CREATE VIEW UsersWith3DayStreaks AS
SELECT
user_id,
COUNT(*) AS streak_length
FROM UserStreakLengths
GROUP BY user_id, streak_id
HAVING COUNT(*) >= 3;
SELECT DISTINCT U.user_id, U.username
FROM Users U
JOIN UsersWith3DayStreaks S ON U.user_id = S.user_id;
14 changes: 7 additions & 7 deletions tests/test_sql_queries.py
Original file line number Diff line number Diff line change
Expand Up @@ -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='postgres',
user='postgres',
password='toor',
host='127.0.0.1',
port='5432'
)
self.cur = self.conn.cursor()

Expand All @@ -21,7 +21,7 @@ def tearDown(self):

def test_task1(self):
# Task 1: Example SQL query in task1.sql
with open('/sql/task1.sql', 'r') as file:
with open('./sql/task1.sql', 'r') as file:
sql_query = file.read()

self.cur.execute(sql_query)
Expand All @@ -36,7 +36,7 @@ def test_task1(self):

def test_task2(self):
# Task 2: Example SQL query in task2.sql
with open('/sql/task2.sql', 'r') as file:
with open('./sql/task2.sql', 'r') as file:
sql_query = file.read()

self.cur.execute(sql_query)
Expand Down