Feat: All queries should work

This commit is contained in:
minhtrannhat 2024-07-22 12:18:06 -04:00
parent 2a77c8e75a
commit 7ae9cca86f
4 changed files with 251 additions and 63 deletions

4
.idea/dataSources.xml generated
View File

@ -1,11 +1,11 @@
<?xml version="1.0" encoding="UTF-8"?>
<project version="4">
<component name="DataSourceManagerImpl" format="xml" multifile-model="true">
<data-source source="LOCAL" name="@localhost" uuid="ab0522bd-1cfb-4e09-a121-85218f5838de">
<data-source source="LOCAL" name="comp353_mysql" uuid="b67e188d-0253-410c-ab68-976c96cf5231">
<driver-ref>mysql.8</driver-ref>
<synchronize>true</synchronize>
<jdbc-driver>com.mysql.cj.jdbc.Driver</jdbc-driver>
<jdbc-url>jdbc:mysql://localhost:32768</jdbc-url>
<jdbc-url>jdbc:mysql://localhost:32770</jdbc-url>
<jdbc-additional-properties>
<property name="com.intellij.clouds.kubernetes.db.host.port" />
<property name="com.intellij.clouds.kubernetes.db.enabled" value="false" />

2
.idea/misc.xml generated
View File

@ -8,7 +8,7 @@
</list>
</option>
</component>
<component name="ProjectRootManager" version="2" languageLevel="JDK_21" default="true" project-jdk-name="21" project-jdk-type="JavaSDK">
<component name="ProjectRootManager" version="2" languageLevel="JDK_22" default="true" project-jdk-name="22 (WSL) (2)" project-jdk-type="JavaSDK">
<output url="file://$PROJECT_DIR$/out" />
</component>
</project>

17
.idea/remote-targets.xml generated Normal file
View File

@ -0,0 +1,17 @@
<?xml version="1.0" encoding="UTF-8"?>
<project version="4">
<component name="RemoteTargetsManager">
<targets>
<target name="WSL" type="wsl" uuid="7302c38c-ccf3-49a1-9c57-af5328fb49f8">
<config>
<option name="distributionMsId" value="Ubuntu" />
</config>
<ContributedStateBase type="JavaLanguageRuntime">
<config>
<option name="homePath" value="/home/minhradz/.jdks/openjdk-22.0.1" />
</config>
</ContributedStateBase>
</target>
</targets>
</component>
</project>

View File

@ -44,23 +44,26 @@ CREATE TABLE Products
);
-- Create Sales table
--
-- If DeliverToCity is NOT NULL, then this sale needs to be delivered
CREATE TABLE Sales
(
SaleID INT PRIMARY KEY AUTO_INCREMENT,
SaleDate DATE NOT NULL,
TotalAmount DECIMAL(10, 2) NOT NULL,
TotalAmount DECIMAL(10, 2) DEFAULT 0,
ClientID INT,
DeliveryFee DECIMAL(10, 2),
DeliverToCity VARCHAR(50),
DeliveryFee DECIMAL(10, 2) DEFAULT 0,
FOREIGN KEY (ClientID) REFERENCES Member (MemberID)
);
-- Create SalesItems table
--
CREATE TABLE SalesItems
(
SaleItemID INT PRIMARY KEY AUTO_INCREMENT,
SaleID INT,
ProductID INT,
Quantity INT,
FOREIGN KEY (SaleID) REFERENCES Sales (SaleID),
FOREIGN KEY (ProductID) REFERENCES Products (ProductID)
);
@ -88,6 +91,38 @@ CREATE TABLE Expenses
-- Add constraints and triggers
-- Ensure Product is in stock before the Sale
CREATE TRIGGER chk_product_in_stock
BEFORE INSERT
ON SalesItems
FOR EACH ROW
BEGIN
DECLARE product_count INT;
DECLARE is_in_stock BOOLEAN;
-- Check if product exists
SELECT COUNT(*)
INTO product_count
FROM Products
WHERE ProductID = NEW.ProductID;
IF product_count = 0 THEN
SIGNAL SQLSTATE '45000'
SET MESSAGE_TEXT = 'Product does not exist. Failed to create SalesItems';
ELSE
-- If product exists, check if it's in stock
SELECT InStock
INTO is_in_stock
FROM Products
WHERE ProductID = NEW.ProductID;
IF NOT is_in_stock THEN
SIGNAL SQLSTATE '45000'
SET MESSAGE_TEXT = 'Product is not in stock. Failed to create SalesItems';
END IF;
END IF;
END;
-- Ensure only presidents can approve expenses
CREATE TRIGGER chk_president_approval_insert
BEFORE INSERT
@ -108,7 +143,6 @@ END IF;
END;
-- Trigger to update product stock status when sold
DELIMITER //
CREATE TRIGGER update_product_stock
AFTER INSERT
ON SalesItems
@ -116,34 +150,70 @@ CREATE TRIGGER update_product_stock
BEGIN
UPDATE Products SET InStock = FALSE WHERE ProductID = NEW.ProductID;
END;
//
DELIMITER ;
-- Trigger to calculate and update delivery fee
DELIMITER //
CREATE TRIGGER calculate_delivery_fee
-- Create sale only for registered client
CREATE TRIGGER check_client_before_sale
BEFORE INSERT
ON Sales
FOR EACH ROW
BEGIN
DECLARE total_weight DECIMAL(10, 2);
DECLARE client_exists INT;
SELECT SUM(p.Weight * si.Quantity)
INTO total_weight
-- Check if the ClientID exists in the Member table
SELECT COUNT(*)
INTO client_exists
FROM Member
WHERE MemberID = NEW.ClientID;
-- If the client doesn't exist, raise an error
IF client_exists = 0 THEN
SIGNAL SQLSTATE '45000'
SET MESSAGE_TEXT = 'Error: Cannot create sale for unregistered client.';
END IF;
END;
-- Calculate the delivery fees
CREATE TRIGGER calculate_delivery_fee_and_total
AFTER INSERT
ON SalesItems
FOR EACH ROW
BEGIN
DECLARE total_weight DECIMAL(10, 2);
DECLARE total_amount DECIMAL(10, 2);
DECLARE delivery_city VARCHAR(50);
DECLARE delivery_fee DECIMAL(10, 2);
-- Calculate total weight and total amount of all items in the sale
SELECT SUM(p.Weight), SUM(p.SellingPrice), s.DeliverToCity
INTO total_weight, total_amount, delivery_city
FROM SalesItems si
JOIN Products p ON si.ProductID = p.ProductID
WHERE si.SaleID = NEW.SaleID;
JOIN Sales s ON si.SaleID = s.SaleID
WHERE si.SaleID = NEW.SaleID
GROUP BY si.SaleID;
SET NEW.DeliveryFee = total_weight * 6.50;
SET NEW.TotalAmount = NEW.TotalAmount + NEW.DeliveryFee;
IF delivery_city IS NOT NULL THEN
-- Calculate delivery fee
SET delivery_fee = total_weight * 6.50;
-- Update total amount to include delivery fee
SET total_amount = total_amount + delivery_fee;
ELSE
-- If not delivered, ensure DeliveryFee is 0
SET delivery_fee = 0;
END IF;
-- Update the Sales record
UPDATE Sales
SET TotalAmount = total_amount,
DeliveryFee = delivery_fee
WHERE SaleID = NEW.SaleID;
END;
//
DELIMITER ;
-- Insert data into Member table
INSERT INTO Member (FirstName, LastName, MiddleInitial, DateOfBirth, Address, Gender, PhoneNumber, EmailAddress,
SocialSecurityNumber, MembershipStartDate, MemberType)
VALUES ('John', 'Doe', 'A', '1980-05-15', '123 Main St, Anytown, USA', 'Male', '555-123-4567', 'john.doe@email.com',
VALUES ('John', 'Doe', 'A', '1980-05-15', '123 Main St, Anytown, USA', 'Male', '555-123-4567',
'john.doe@email.com',
'123-45-6789', '2022-01-01', 'Donor'),
('Jane', 'Smith', 'B', '1985-08-22', '456 Elm St, Somewhere, USA', 'Female', '555-987-6543',
'jane.smith@email.com', '987-65-4321', '2022-02-15', 'Client'),
@ -152,32 +222,50 @@ VALUES ('John', 'Doe', 'A', '1980-05-15', '123 Main St, Anytown, USA', 'Male', '
('Darton', 'Johnson', 'C', '1972-11-11', '789 Oak St, Nowhere, USA', 'Male', '561-216-8835',
'darton.johnson@email.com', '148-46-2580', '2020-03-01', 'Employee'),
('Alice', 'Williams', 'D', '1990-11-30', '321 Pine St, Everywhere, USA', 'Female', '555-369-2580',
'alice.williams@email.com', '369-25-8014', '2022-04-15', 'Donor');
'alice.williams@email.com', '369-25-8014', '2022-04-15', 'Donor'),
('David', 'Williams', 'D', '1945-12-30', '311 Pine St, Everywhere, USA', 'Male', '565-109-2888',
'david.williams@email.com', '379-25-8014', '2022-04-15', 'Client'),
('Brenda', 'Williams', 'D', '1930-01-30', '331 Pine St, Everywhere, USA', 'Female', '556-201-1370',
'brenda.williams@email.com', '269-25-8014', '2022-04-15', 'Client');
-- Insert data into Donations table
INSERT INTO Donations (DonorID, DonationDate, DonationType, DonationAmount)
VALUES (1, '2023-01-15', 'Money', 500.00),
(4, '2023-02-20', 'Products', NULL),
(2, '2023-02-20', 'Products', NULL),
(1, '2023-03-10', 'Money', 250.00),
(4, '2023-04-05', 'Products', NULL);
(2, '2023-04-05', 'Products', NULL);
-- Insert data into Products table
INSERT INTO Products (Description, DonationDate, SellingPrice, Weight, InStock, DonationID)
VALUES ('Laptop', '2023-02-20', 300.00, 2.5, TRUE, 2),
('Chair', '2023-02-20', 50.00, 5.0, TRUE, 2),
('Bookshelf', '2023-04-05', 100.00, 20.0, TRUE, 4),
('Microwave', '2023-04-05', 75.00, 10.0, TRUE, 4);
('Microwave', '2023-04-05', 75.00, 10.0, TRUE, 4),
('TV', '2023-04-05', 55.00, 10.0, TRUE, 4),
('Table', '2023-04-05', 50.00, 10.0, TRUE, 4),
('OLED TV', '2021-04-05', 57.00, 10.0, TRUE, 4),
('Table (Broken)', '2021-04-05', 58.00, 10.0, TRUE, 4);
-- Insert data into Sales table
INSERT INTO Sales (SaleDate, TotalAmount, ClientID, DeliveryFee)
VALUES ('2023-05-01', 350.00, 2, NULL),
('2023-05-15', 100.00, 2, NULL);
INSERT INTO Sales (SaleDate, ClientID, DeliverToCity)
VALUES ('2024-06-02', 2, 'Brossard'),
('2024-06-15', 3, 'Saint Lambert'),
('2023-07-15', 3, NULL),
('2023-01-15', 6, NULL),
('2023-01-15', 7, NULL),
('2023-07-15', 6, NULL),
('2023-07-15', 7, NULL);
-- Insert data into SalesItems table
INSERT INTO SalesItems (SaleID, ProductID, Quantity)
VALUES (1, 1, 1),
(1, 2, 1),
(2, 3, 1);
INSERT INTO SalesItems (SaleID, ProductID)
VALUES (1, 1),
(1, 2),
(2, 3),
(3, 4),
(4, 5),
(5, 6),
(6, 7),
(7, 8);
-- Insert data into Employees table
INSERT INTO Employees (EmployeeID, JobTitle, Salary)
@ -186,17 +274,16 @@ VALUES (3, 'President', 100000.00),
-- Insert data into Expenses table
INSERT INTO Expenses (ApprovedByID, PaymentDate, Amount, ExpenseType, Description)
VALUES (3, '2023-06-01', 2000.00, 'Rent', 'Monthly office rent'),
(3, '2023-06-05', 500.00, 'Bill Payment', 'Electricity bill'),
(3, '2023-06-10', 1000.00, 'Charity Payment', 'Donation to local food bank');
VALUES (3, '2024-01-02', 2000.00, 'Rent', 'Monthly office rent'),
(3, '2024-06-05', 500.00, 'Bill Payment', 'Electricity bill'),
(3, '2024-06-10', 1000.00, 'Charity Payment', 'Donation to local food bank');
-- Part 2 Question 1
# List the details of all the clients that are not volunteer employees and donors as well.
# Details include client ID, first-name, last-name, middle-initial, date-of-birth, address,
# gender, phone-number, email-address, social-security-number, job-title, and the start date
# of membership
SELECT
m.MemberID AS ClientID,
SELECT m.MemberID AS ClientID,
m.FirstName,
m.LastName,
m.MiddleInitial,
@ -208,14 +295,98 @@ SELECT
m.SocialSecurityNumber,
e.JobTitle,
m.MembershipStartDate
FROM
Member m
FROM Member m
LEFT JOIN Employees e ON m.MemberID = e.EmployeeID
WHERE
m.MemberType = 'Client'
AND m.MemberID IN (
SELECT DISTINCT DonorID
WHERE m.MemberType = 'Client'
OR m.MemberID IN (SELECT DISTINCT DonorID
FROM Donations
WHERE DonorID IS NOT NULL
)
WHERE DonorID IS NOT NULL)
AND (e.EmployeeID IS NULL OR e.Salary > 0);
-- Part 2: Question 2
# List the details of all the expenses that are paid in the months of Jan to June of 2024.
# Details includes expense ID, first name and last name of the president who approved the
# expense, the date of the payment of the expense, the amount of the expense, the type of
# the expense, and the description of the expense
SELECT Expenses.ExpenseID,
Member.FirstName AS PresidentFirstName,
Member.LastName AS PresidentLastName,
Expenses.PaymentDate,
Expenses.Amount,
Expenses.ExpenseType,
Expenses.Description
FROM Expenses
INNER JOIN Member on Expenses.ApprovedByID = MemberID
WHERE Expenses.PaymentDate BETWEEN '2024-01-01' AND '2024-06-30';
-- Part 2 Question 3
# Give a report of the sales that have been delivered to the cities of Brossard and Saint
# Lambert in June 2024. Details include sale ID, date of the sale, clients first name and last
# name, product description, price and weight of the product. Results should be displayed
# in ascending order by saleID, then by first name, then by last name, then by weight of the
# product.
SELECT s.SaleID,
s.SaleDate,
m.FirstName AS ClientFirstName,
m.LastName AS ClientLastName,
p.Description AS ProductDescription,
p.SellingPrice AS ProductPrice,
p.Weight AS ProductWeight
FROM Sales s
JOIN
Member m ON s.ClientID = m.MemberID
JOIN
SalesItems si ON s.SaleID = si.SaleID
JOIN
Products p ON si.ProductID = p.ProductID
WHERE s.SaleDate BETWEEN '2024-06-01' AND '2024-06-30'
AND (s.DeliverToCity = 'Brossard'
OR s.DeliverToCity = 'Saint Lambert')
AND s.DeliveryFee > 0
ORDER BY s.SaleID ASC,
m.FirstName ASC,
m.LastName ASC,
p.Weight ASC;
-- Question 2 part 4
# Give a monthly report of the sales that have been picked up by the buyers in 2023. For
# every month of 2023, details include number of products sold, , average of price of all
# products sold, and average weight of the products sold. Results should be displayed in
# descending order by number of products sold
SELECT DATE_FORMAT(s.SaleDate, '%Y-%m') AS Month,
COUNT(si.ProductID) AS ProductsSold,
AVG(p.SellingPrice) AS AveragePrice,
AVG(p.Weight) AS AverageWeight
FROM Sales s
JOIN
SalesItems si ON s.SaleID = si.SaleID
JOIN
Products p ON si.ProductID = p.ProductID
WHERE YEAR(s.SaleDate) = 2023
AND s.DeliveryFee = 0
GROUP BY DATE_FORMAT(s.SaleDate, '%Y-%m')
ORDER BY ProductsSold DESC;
-- Part 2 Question 5
# For every client who is registered in the system and did not make any purchase since
# January 1st 2024, give a report of the sales she/he has done since her/his membership. The
# report should include the clients first and last name, the date of the first sale she/he has
# made, the date of the last sale she/he has made, the total amount of sales she/he has made.
# The results should be displayed in decreasing order by total amount of sales.
SELECT m.FirstName,
m.LastName,
MIN(s.SaleDate) AS FirstSaleDate,
MAX(s.SaleDate) AS LastSaleDate,
SUM(s.TotalAmount) AS TotalSalesAmount
FROM Member m
LEFT JOIN
Sales s ON m.MemberID = s.ClientID
WHERE m.MemberType = 'Client'
AND m.MemberID NOT IN (SELECT DISTINCT ClientID
FROM Sales
WHERE SaleDate >= '2024-01-01')
GROUP BY m.MemberID
HAVING
COUNT(s.SaleID) > 0
ORDER BY TotalSalesAmount DESC;