0% found this document useful (0 votes)
11 views27 pages

DB Foundation-Project 3

This document outlines an assignment focused on creating an Online Food Ordering System using SQL, covering advanced query writing, transaction control, indexes, triggers, and stored procedures. It includes specific tasks such as creating views, finding top customers, managing orders, and implementing database optimizations. The document provides SQL code examples and explanations for each task to facilitate learning and application of SQL concepts.
Copyright
© © All Rights Reserved
We take content rights seriously. If you suspect this is your content, claim it here.
Available Formats
Download as PDF, TXT or read online on Scribd
0% found this document useful (0 votes)
11 views27 pages

DB Foundation-Project 3

This document outlines an assignment focused on creating an Online Food Ordering System using SQL, covering advanced query writing, transaction control, indexes, triggers, and stored procedures. It includes specific tasks such as creating views, finding top customers, managing orders, and implementing database optimizations. The document provides SQL code examples and explanations for each task to facilitate learning and application of SQL concepts.
Copyright
© © All Rights Reserved
We take content rights seriously. If you suspect this is your content, claim it here.
Available Formats
Download as PDF, TXT or read online on Scribd
You are on page 1/ 27

DB FOUNDATION – ASSIGNMENT 3

Use Case: Online Food Ordering System

Objective:

In this assignment, you will practice views, joins, subqueries,


transaction control, indexes, triggers, stored procedures, and functions.

Recommended Tool:

 Oracle LiveSQL
 Mysql Workbench

Part A – Advanced Query Writing

Create a view named CustomerOrdersView that shows


customer name , order_id, order_date, and total_amount.

To create a SQL view named CustomerOrdersView that displays


customer name, order_id, order_date, and total_amount, you need the
following information from your database:

- The table containing customer names (usually a Customers or Users


table).

- The table(s) containing orders, including order_id, order_date,


total_amount, and a way to relate orders to customers (e.g.,
customer_id).

Assuming the typical table structure:

- customers: customer_id, customer_name, ...


- orders: order_id, customer_id, order_date, total_amount, ...

Here is the SQL statement to create the desired view:

sql

CREATE VIEW CustomerOrdersView AS

SELECT

c.customer_name,

o.order_id,

o.order_date,

o.total_amount

FROM

customers c

JOIN orders o ON c.customer_id = o.customer_id;

If your table or column names differ, replace them accordingly. This


view will give you a simple way to query customer names alongside
their order details.

Display the top 3 Customers who spent the most on orders

To display the top 3 customers who spent the most on orders, you’ll
want to sum each customer’s total amount spent and then pick the top
three. Assuming the same table structure as before (customers and
orders tables), you can use the following SQL query:
sql

SELECT

c.customer_name,

SUM(o.total_amount) AS total_spent

FROM

customers c

JOIN orders o ON c.customer_id = o.customer_id

GROUP BY

c.customer_name

ORDER BY

total_spent DESC

LIMIT 3;

This query joins customers to their orders, sums up the amount each
customer has spent, sorts them by that sum in descending order, and
returns only the top three customers. If your tables or columns have
different names, adjust accordingly.

Find all restaurants that have not received any views.


Find all restaurants that have not received any reviews

To find all restaurants that have not received any reviews, you typically
need two tables:

- restaurants: restaurant_id, restaurant_name, etc.


- reviews: review_id, restaurant_id, review_text, etc.

You can use a LEFT JOIN to identify restaurants without matching


reviews, or a NOT EXISTS subquery. Here are two common SQL
approaches:

Using LEFT JOIN

sql

SELECT r.restaurant_id, r.restaurant_name

FROM restaurants r

LEFT JOIN reviews rv ON r.restaurant_id = rv.restaurant_id

WHERE rv.review_id IS NULL;

Using NOT EXISTS

sql

SELECT r.restaurant_id, r.restaurant_name

FROM restaurants r

WHERE NOT EXISTS (

SELECT 1 FROM reviews rv WHERE rv.restaurant_id = r.restaurant_id

);

Both queries will return all restaurants for which there are no
corresponding reviews in the reviews table. Adjust table or column
names as needed for your schema.
To find all restaurants that have not received any reviews, you typically
need two tables:

- restaurants: restaurant_id, restaurant_name, etc.

- reviews: review_id, restaurant_id, review_text, etc.

You can use a LEFT JOIN to identify restaurants without matching


reviews, or a NOT EXISTS subquery. Here are two common SQL
approaches:

Using LEFT JOIN

sql

SELECT r.restaurant_id, r.restaurant_name

FROM restaurants r

LEFT JOIN reviews rv ON r.restaurant_id = rv.restaurant_id

WHERE rv.review_id IS NULL;

Using NOT EXISTS

sql

SELECT r.restaurant_id, r.restaurant_name

FROM restaurants r

WHERE NOT EXISTS (

SELECT 1 FROM reviews rv WHERE rv.restaurant_id = r.restaurant_id

);
Both queries will return all restaurants for which there are no
corresponding reviews in the reviews table. Adjust table or column
names as needed for your schema.

Write a query to display the order_id, item_name, quantity, and


subtotal (quantity*price) for each order.

Write a query to display the order_id, item_name, quantity, and


subtotal

(quantity × price) for each order.

Assuming your database has the following common structure:

- orders: order_id, ...

- order_items: order_id, item_id, quantity, price

- items: item_id, item_name, ...

Here is a SQL query that displays order_id, item_name, quantity, and


the subtotal (quantity × price) for each order:

sql

SELECT

oi.order_id,

i.item_name,

oi.quantity,

(oi.quantity * oi.price) AS subtotal

FROM
order_items oi

JOIN items i ON oi.item_id = i.item_id;

If your table or column names are different, adjust them accordingly.


This query pulls each order's details, including the calculated subtotal
for each item in the order.

Use a nested query to find customers who ordered the most


expensive food item

Use a nested query to find customers who ordered the most expensive
food

item

Here’s how you can write a SQL query, using a nested (subquery), to
find all customers who have ordered the *most expensive food item*.
Assume the following tables:

- customers: customer_id, customer_name

- orders: order_id, customer_id

- order_items: order_id, item_id, quantity, price

- items: item_id, item_name

Query

sql

SELECT DISTINCT c.customer_id, c.customer_name

FROM customers c

JOIN orders o ON c.customer_id = o.customer_id


JOIN order_items oi ON o.order_id = oi.order_id

WHERE oi.item_id = (

SELECT item_id

FROM items

ORDER BY price DESC

LIMIT 1

);

*Explanation:*

- The subquery finds the item_id of the food item with the highest
price.

- The main query selects all distinct customers who have an order_item
with this item_id.

If the highest price occurs for multiple items, use IN instead of = and
adapt the subquery:

sql

WHERE oi.item_id IN (

SELECT item_id

FROM items

WHERE price = (SELECT MAX(price) FROM items)

Change table and column names as necessary for your schema.


Show the restaurant and food item names where the discount
(offer) is greater than 20%

Show the restaurant and food item names where the discount (offer) is

greater than 20%.

Assuming you have these tables:

- restaurants: restaurant_id, restaurant_name

- items (or food_items): item_id, restaurant_id, item_name, discount


(or offer) — where discount is a percentage value

Here is a SQL query to show the restaurant name and food item name
where the discount is greater than 20%:

sql

SELECT

r.restaurant_name,

i.item_name

FROM

restaurants r

JOIN items i ON r.restaurant_id = i.restaurant_id

WHERE

i.discount > 20;


Modify the table and column names if necessary for your database
schema. This query filters for items with a discount greater than 20%
and lists the corresponding restaurant and item names.

Part B –Transaction Control(TCL)

Insert a new order into the Orders and OrderDetails tables

Insert a new order into the Orders and OrderDetails tables.

To insert a new order, you typically need to insert data into two tables:

- Orders: stores order-level details (e.g., order_id, customer_id,


order_date, total_amount)

- OrderDetails (or Order_Items): stores item-level details for each order


(e.g., order_id, item_id, quantity, price)

Assuming the typical columns in each table:

- Orders(order_id, customer_id, order_date, total_amount)

- OrderDetails(order_detail_id, order_id, item_id, quantity, price)

Here’s an example SQL to insert a new order and its details. Note that
order_id and order_detail_id might be auto-generated (e.g., auto-
increment).

Insert into Orders

sql

INSERT INTO Orders (customer_id, order_date, total_amount)

VALUES (123, CURRENT_DATE, 250.00);


Assuming order_id is auto-generated, you need to retrieve it before
inserting into OrderDetails. In many databases, you can do this with
LAST_INSERT_ID() or returning clauses.

Insert into OrderDetails (example 2 items)

sql

-- Assume the last generated order_id can be retrieved as @order_id

INSERT INTO OrderDetails (order_id, item_id, quantity, price)

VALUES

(@order_id, 101, 2, 50.00),

(@order_id, 102, 3, 50.00);

If your database doesn’t support variables like @order_id, you need to


retrieve the last inserted order ID in your application code or use
appropriate SQL syntax for your DBMS.

Replace the values with actual data for your use case. Let me know if
you want the syntax for a specific database system.

Use SAVEPOINT after inserting the order but before inserting


the details.

Use SAVEPOINT after inserting the order but before inserting the
details.
Using a SAVEPOINT allows you to set a point within a transaction to
which you can later roll back without affecting the entire transaction.
This is useful if you want to insert the order first, set a savepoint, and
then attempt to insert the order details, and if something goes wrong,
you can roll back to the savepoint instead of rolling back the entire
transaction.

Here’s an example SQL workflow with SAVEPOINT for inserting an order


and order details:

sql

BEGIN TRANSACTION;

-- Insert into Orders

INSERT INTO Orders (customer_id, order_date, total_amount)

VALUES (123, CURRENT_DATE, 250.00);

-- Set savepoint after inserting the order

SAVEPOINT order_inserted;

-- Insert into OrderDetails (example for 2 items)

INSERT INTO OrderDetails (order_id, item_id, quantity, price)

VALUES

(LAST_INSERT_ID(), 101, 2, 50.00),

(LAST_INSERT_ID(), 102, 3, 50.00);

-- If all good, commit

COMMIT;
If an error occurs while inserting into OrderDetails, you can roll back to
the savepoint and decide how to handle it (e.g., retry or rollback the
entire transaction):

sql

ROLLBACK TO SAVEPOINT order_inserted;

-- Then either COMMIT or ROLLBACK the entire transaction depending


on the situation

Note: The exact SQL syntax and function to get the last inserted
order_id (e.g., LAST_INSERT_ID()) depend on your database system
(MySQL, PostgreSQL, SQL Server, etc.). Adjust accordingly.

Rolllback to the savepoint and check if the order details still exist.

Rollback to the savepoint and check if the order details still exist.

When you rollback to a savepoint, all changes made after that


savepoint are undone, but changes made before it remain. In this case,
rolling back to the savepoint after inserting the order but before
inserting the order details will remove the inserted order details but
keep the order itself.

Here’s the conceptual SQL flow:

sql

-- Rollback to savepoint to undo order details insert

ROLLBACK TO SAVEPOINT order_inserted;


After rolling back, to check if the order details still exist (they should
not), run a query like:

sql

SELECT *

FROM OrderDetails

WHERE order_id = (SELECT LAST_INSERT_ID());

This query should return no rows because the rollback to savepoint


removes all inserts to OrderDetails that happened after the savepoint.

To check the order still exists (it should), run:

sql

SELECT *

FROM Orders

WHERE order_id = (SELECT LAST_INSERT_ID());

You will find the order record remains after rollback to the savepoint.

Note: Depending on your database system, the method to get the


relevant order_id might be different; if you stored the order_id in a
variable at insert time, use that variable for these checks.

Finally, COMMIT the transaction.

Finally, COMMIT the transaction.

To finalize all changes and make them permanent after working with
savepoints and rollback, you execute the COMMIT statement:
sql

COMMIT;

This will commit the transaction, saving the inserted order and any
other changes made up to this point to the database permanently.

Part C – Indexes & Optimization

Create an index on the email column of the Customer table

Create an index on the email column of the Customer table.

To create an index on the email column of the Customer table, you can
use the following SQL statement:

sql

CREATE INDEX idx_customer_email ON Customer(email);

This index will improve the performance of queries that filter or search
by the email column. Adjust table or column names if needed.

Create an index on the restaurant_id column of the FoodItem


table.

Create an index on the restaurant_id column of the FoodItem table.

To create an index on the restaurant_id column of the FoodItem table,


use this SQL statement:

sql

CREATE INDEX idx_fooditem_restaurant_id ON


FoodItem(restaurant_id);
This index will enhance query performance involving the restaurant_id
column in the FoodItem table. Adjust names if your schema uses
different identifiers.

Add a short SQL comment explaining how indexes help improve


query performance.

Add a short SQL comment explaining how indexes help improve query

performance.

sql

-- Indexes improve query performance by allowing the database to


quickly locate and access the rows matching a search condition without
scanning the entire table.

Citations:

[1] Comments in SQL (with examples) - CodeChef


https://www.codechef.com/blogs/comments-in-sql

[2] SQL Comments - W3Schools


https://www.w3schools.com/sql/sql_comments.asp

[3] Comments Within SQL Statements


https://docs.oracle.com/cd/B13789_01/server.101/b10759/sql_eleme
nts006.htm

[4] SQL Comment Essentials: Mastering Code Annotation in Databases


https://www.dbvis.com/thetable/sql-comment-a-comprehensive-
guide/
[5] SQL Comments - GeeksforGeeks
https://www.geeksforgeeks.org/sql/sql-comments/

[6] MySQL Comments - W3Schools


https://www.w3schools.com/mysql/mysql_comments.asp

[7] SQL Comments - Syntax, Use Cases, and Examples | Hightouch


https://hightouch.com/sql-dictionary/sql-comments

[8] SQL Comments (With Examples) - Programiz


https://www.programiz.com/sql/comments

[9] -- (Comment) (Transact-SQL) - SQL Server | Microsoft Learn


https://learn.microsoft.com/en-us/sql/t-sql/language-elements/comme
nt-transact-sql?view=sql-server-ver17

Part D – Triggers

Create a trigger named OrderStatusTrigger that


automaticallysets the status column in the Orders table to
‘pending’ when a new order is inserted.

1. Create a trigger named OrderStatusTrigger that automatically sets


the status

column in the Orders table to 'Pending' when a new order is inserted.

Here is an example SQL statement to create a trigger named


OrderStatusTrigger that sets the status column to 'Pending'
automatically when a new order is inserted into the Orders table. The
syntax varies slightly between database systems; here is a general
example for MySQL:
sql

DELIMITER //

CREATE TRIGGER OrderStatusTrigger

BEFORE INSERT ON Orders

FOR EACH ROW

BEGIN

SET NEW.status = 'Pending';

END;

//

DELIMITER ;

This trigger fires before a new row is inserted into the Orders table and
sets the status field to 'Pending'. Adjust syntax if you are using a
different database system.

Verify the trigger by inserting a new order and checking its


status.

Verify the trigger by inserting a new order and checking its status.

To verify the OrderStatusTrigger, first insert a new order without


specifying the status, then query the inserted order to check if the
status was automatically set to 'Pending'.

1. Insert a new order (without specifying status):

sql
INSERT INTO Orders (customer_id, order_date, total_amount)

VALUES (123, CURRENT_DATE, 100.00);

2. Check the status of the newly inserted order:

If order_id is auto-incrementing, you can find the latest order for the
customer:

sql

SELECT order_id, status

FROM Orders

WHERE customer_id = 123

ORDER BY order_date DESC, order_id DESC

LIMIT 1;

This should show the inserted order with the status as 'Pending',
confirming the trigger works correctly.

Part E – Stored Procedures & Functions

Create a stored procedure AddNewCustomer that inserts a new


customer into the Customer table(accept parameters like name,
email, phone, address).

Create a stored procedure AddNewCustomer that inserts a new


customer

into the Customer table (accept parameters like name, email, phone,

address).
Here is an example of a stored procedure named AddNewCustomer
that inserts a new customer into the Customer table. It accepts
parameters for name, email, phone, and address. This example is for
MySQL:

sql

DELIMITER //

CREATE PROCEDURE AddNewCustomer(

IN p_name VARCHAR(100),

IN p_email VARCHAR(100),

IN p_phone VARCHAR(20),

IN p_address VARCHAR(255)

BEGIN

INSERT INTO Customer (name, email, phone, address)

VALUES (p_name, p_email, p_phone, p_address);

END;

//

DELIMITER ;
You can call this procedure by passing the customer details as
arguments. Adjust data types and lengths to match your table schema if
different.sql

CREATE VIEW CustomerOrdersView AS

SELECT

c.customer_name,

o.order_id,

o.order_date,

o.total_amount

FROM

customers c

JOIN orders o ON c.customer_id = o.customer_id;

Create a function CalculateOrderTotal(ordered) that returns the


total amount for a given order by swimming up (quantity* price)
from OrderDetails and FoodItem.

Create a function CalculateOrderTotal(orderId) that returns the total


amount

for a given order by summing up (quantity × price) from OrderDetails


and

FoodItem.
Here is an example of a SQL function CalculateOrderTotal(orderId) that
calculates the total amount for a given order by summing up (quantity ×
price) from OrderDetails joined with FoodItem (assuming the price is in
FoodItem). This example is for MySQL:

sql

DELIMITER //

CREATE FUNCTION CalculateOrderTotal(p_orderId INT)

RETURNS DECIMAL(10, 2)

DETERMINISTIC

BEGIN

DECLARE total DECIMAL(10, 2);

SELECT SUM(od.quantity * fi.price) INTO total

FROM OrderDetails od

JOIN FoodItem fi ON od.item_id = fi.item_id

WHERE od.order_id = p_orderId;

RETURN IFNULL(total, 0);

END;

//

DELIMITER ;
This function takes an orderId as input and returns the total amount by
multiplying quantity and price for all items in that order. Adjust table
and column names if different in your schema.

Demonstrate both by:


o Calling the procedure to insert a new customer.
o Calling the function to calculate the total for a specific order.

Demonstrate both by:

○ Calling the procedure to insert a new customer.

○ Calling the function to calculate the total for a specific order.

Here’s how you can demonstrate both the stored procedure


AddNewCustomer for inserting a new customer and the function
CalculateOrderTotal to calculate the total amount for a specific order.

1. Calling the stored procedure to insert a new customer:

sql

CALL AddNewCustomer('John Doe', '[email protected]', '123-


456-7890', '123 Elm Street');

This will insert a new customer with the given name, email, phone, and
address into the Customer table.

2. Calling the function to calculate the total for a specific order:

Assuming you want to calculate the total for order ID 101:

sql

SELECT CalculateOrderTotal(101) AS total_amount;


This will return the total amount for the order with ID 101 by summing
quantity × price from OrderDetails joined with FoodItem.

Submission
Conclusion

The Food Ordering System database was successfully designed and


implemented using DBMS concepts. Key entities such as Customer,
Restaurant, FoodItem, Orders, OrderDetails, Review, and Offer were
created with appropriate constraints like PRIMARY KEY, FOREIGN
KEY, NOT NULL, UNIQUE, and CHECK to maintain data integrity and
consistency.

With this system:


• Customers can be stored and managed efficiently.

• Restaurants and their food items are properly linked.

• Orders can be tracked for each customer along with order


details.

• Reviews and offers add more features for customer


engagement.

By applying SQL queries (SELECT, JOIN, WHERE, etc.), users can


retrieve meaningful insights like:

• All orders placed by a specific customer.

• All food items with their respective restaurants.

• Customer reviews and restaurant offers.

This structured relational database ensures accuracy, reliability, and


scalability, making it suitable for real-world online food
ordering platforms.

You might also like