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,
ClientID INT,
DeliveryFee DECIMAL(10, 2),
SaleID INT PRIMARY KEY AUTO_INCREMENT,
SaleDate DATE NOT NULL,
TotalAmount DECIMAL(10, 2) DEFAULT 0,
ClientID INT,
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
@ -104,11 +139,10 @@ BEGIN
IF job_title != 'President' THEN
SIGNAL SQLSTATE '45000'
SET MESSAGE_TEXT = 'ApprovedByID must refer to an employee with the job title President';
END IF;
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,36 +274,119 @@ 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,
m.FirstName,
m.LastName,
m.MiddleInitial,
m.DateOfBirth,
m.Address,
m.Gender,
m.PhoneNumber,
m.EmailAddress,
m.SocialSecurityNumber,
e.JobTitle,
m.MembershipStartDate
FROM
Member m
LEFT JOIN Employees e ON m.MemberID = e.EmployeeID
WHERE
m.MemberType = 'Client'
AND m.MemberID IN (
SELECT DISTINCT DonorID
FROM Donations
WHERE DonorID IS NOT NULL
)
AND (e.EmployeeID IS NULL OR e.Salary > 0);
SELECT m.MemberID AS ClientID,
m.FirstName,
m.LastName,
m.MiddleInitial,
m.DateOfBirth,
m.Address,
m.Gender,
m.PhoneNumber,
m.EmailAddress,
m.SocialSecurityNumber,
e.JobTitle,
m.MembershipStartDate
FROM Member m
LEFT JOIN Employees e ON m.MemberID = e.EmployeeID
WHERE m.MemberType = 'Client'
OR m.MemberID IN (SELECT DISTINCT DonorID
FROM Donations
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;