Compare commits
10 Commits
aeb96d9ad5
...
8683007ea6
| Author | SHA1 | Date | |
|---|---|---|---|
| 8683007ea6 | |||
| 33e6f1849a | |||
| 096dd3e83a | |||
| 936c1d3ed4 | |||
| 0d75c1c035 | |||
| 9308f5471a | |||
| 05e2863bfd | |||
| aac9358de5 | |||
| 70f6458e03 | |||
| 453a68b01d |
4
.gitignore
vendored
@@ -1,2 +1,6 @@
|
||||
# MySQL Workbench project backup files
|
||||
*.mwb.bak
|
||||
|
||||
# Python
|
||||
.ipynb_checkpoints
|
||||
__pycache__
|
||||
|
||||
@@ -19,7 +19,7 @@ USE `LittleLemonDB` ;
|
||||
-- Table `LittleLemonDB`.`Addresses`
|
||||
-- -----------------------------------------------------
|
||||
CREATE TABLE IF NOT EXISTS `LittleLemonDB`.`Addresses` (
|
||||
`AddressID` INT NOT NULL,
|
||||
`AddressID` INT NOT NULL AUTO_INCREMENT,
|
||||
`Street` VARCHAR(255) NOT NULL,
|
||||
`PostalCode` VARCHAR(12) NOT NULL,
|
||||
`City` VARCHAR(255) NOT NULL,
|
||||
@@ -32,7 +32,7 @@ ENGINE = InnoDB;
|
||||
-- Table `LittleLemonDB`.`Customers`
|
||||
-- -----------------------------------------------------
|
||||
CREATE TABLE IF NOT EXISTS `LittleLemonDB`.`Customers` (
|
||||
`CustomerID` INT NOT NULL,
|
||||
`CustomerID` INT NOT NULL AUTO_INCREMENT,
|
||||
`FirstName` VARCHAR(255) NOT NULL,
|
||||
`LastName` VARCHAR(255) NOT NULL,
|
||||
`PhoneNumber` VARCHAR(45) NOT NULL,
|
||||
@@ -52,7 +52,7 @@ ENGINE = InnoDB;
|
||||
-- Table `LittleLemonDB`.`Employees`
|
||||
-- -----------------------------------------------------
|
||||
CREATE TABLE IF NOT EXISTS `LittleLemonDB`.`Employees` (
|
||||
`EmployeeID` INT NOT NULL,
|
||||
`EmployeeID` INT NOT NULL AUTO_INCREMENT,
|
||||
`FirstName` VARCHAR(255) NOT NULL,
|
||||
`LastName` VARCHAR(255) NOT NULL,
|
||||
`PhoneNumber` VARCHAR(45) NOT NULL,
|
||||
@@ -74,7 +74,7 @@ ENGINE = InnoDB;
|
||||
-- Table `LittleLemonDB`.`Bookings`
|
||||
-- -----------------------------------------------------
|
||||
CREATE TABLE IF NOT EXISTS `LittleLemonDB`.`Bookings` (
|
||||
`BookingID` INT NOT NULL,
|
||||
`BookingID` INT NOT NULL AUTO_INCREMENT,
|
||||
`Reserved` DATETIME NOT NULL,
|
||||
`TableNumber` INT NOT NULL,
|
||||
`CustomerID` INT NOT NULL,
|
||||
@@ -99,7 +99,7 @@ ENGINE = InnoDB;
|
||||
-- Table `LittleLemonDB`.`MenuItems`
|
||||
-- -----------------------------------------------------
|
||||
CREATE TABLE IF NOT EXISTS `LittleLemonDB`.`MenuItems` (
|
||||
`MenuItemID` INT NOT NULL,
|
||||
`MenuItemID` INT NOT NULL AUTO_INCREMENT,
|
||||
`Name` VARCHAR(255) NOT NULL,
|
||||
`Category` VARCHAR(255) NOT NULL,
|
||||
`Price` DECIMAL(6,2) NOT NULL,
|
||||
@@ -112,7 +112,7 @@ ENGINE = InnoDB;
|
||||
-- Table `LittleLemonDB`.`Orders`
|
||||
-- -----------------------------------------------------
|
||||
CREATE TABLE IF NOT EXISTS `LittleLemonDB`.`Orders` (
|
||||
`OrderID` INT NOT NULL,
|
||||
`OrderID` INT NOT NULL AUTO_INCREMENT,
|
||||
`Started` DATETIME NOT NULL,
|
||||
`Finished` DATETIME NULL,
|
||||
`BillAmount` DECIMAL(10,2) NULL,
|
||||
@@ -131,7 +131,7 @@ ENGINE = InnoDB;
|
||||
-- Table `LittleLemonDB`.`OrderItems`
|
||||
-- -----------------------------------------------------
|
||||
CREATE TABLE IF NOT EXISTS `LittleLemonDB`.`OrderItems` (
|
||||
`OrderItemID` INT NOT NULL,
|
||||
`OrderItemID` INT NOT NULL AUTO_INCREMENT,
|
||||
`Ordered` DATETIME NOT NULL,
|
||||
`Delivered` DATETIME NULL,
|
||||
`DeliveryStatus` VARCHAR(45) NOT NULL,
|
||||
|
||||
|
Before Width: | Height: | Size: 102 KiB After Width: | Height: | Size: 102 KiB |
BIN
analysis/LittleLemonAnalysis.twbx
Normal file
BIN
analysis/cuisine_sales_profit_bar_chart.png
Normal file
|
After Width: | Height: | Size: 237 KiB |
BIN
analysis/customer_dashboard_filtered.png
Normal file
|
After Width: | Height: | Size: 205 KiB |
BIN
analysis/customer_dashboard_unfiltered.png
Normal file
|
After Width: | Height: | Size: 285 KiB |
BIN
analysis/customer_sales_bar_chart.png
Normal file
|
After Width: | Height: | Size: 248 KiB |
BIN
analysis/data_source.png
Normal file
|
After Width: | Height: | Size: 399 KiB |
BIN
analysis/profit_line_chart.png
Normal file
|
After Width: | Height: | Size: 247 KiB |
BIN
analysis/sales_bubble_chart.png
Normal file
|
After Width: | Height: | Size: 329 KiB |
6
env.yml
@@ -2,11 +2,11 @@ name: capstone-project
|
||||
channels:
|
||||
- conda-forge
|
||||
dependencies:
|
||||
- pip
|
||||
- python=3.13
|
||||
- pynvim
|
||||
- pytest
|
||||
- pip
|
||||
- jupyter
|
||||
- mysql-connector-python
|
||||
- pynvim
|
||||
- pip:
|
||||
- ruff
|
||||
- basedpyright
|
||||
|
||||
216
promotional_campaign.ipynb
Normal file
@@ -0,0 +1,216 @@
|
||||
{
|
||||
"cells": [
|
||||
{
|
||||
"cell_type": "markdown",
|
||||
"id": "3228e84e-083c-48f6-9913-9d96e2fd0a2a",
|
||||
"metadata": {},
|
||||
"source": [
|
||||
"# Promotional campaign"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "markdown",
|
||||
"id": "71a559ef-75a7-4aca-86aa-10629e047222",
|
||||
"metadata": {},
|
||||
"source": [
|
||||
"## Imports"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "code",
|
||||
"execution_count": 1,
|
||||
"id": "8fe32f7f-09b3-4d9a-af26-4146c500bf44",
|
||||
"metadata": {},
|
||||
"outputs": [],
|
||||
"source": [
|
||||
"from decimal import Decimal\n",
|
||||
"from mysql.connector import CMySQLConnection, Error, connect\n",
|
||||
"from mysql.connector.cursor_cext import CMySQLCursor"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "markdown",
|
||||
"id": "70da0c3b-ae18-4b60-a7eb-1c0c75c3677a",
|
||||
"metadata": {},
|
||||
"source": [
|
||||
"## Task 1"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "code",
|
||||
"execution_count": 2,
|
||||
"id": "ac95c33d-3ead-4dab-b007-4f20d37f7386",
|
||||
"metadata": {},
|
||||
"outputs": [],
|
||||
"source": [
|
||||
"connection = connect(\n",
|
||||
" user=\"tobias\",\n",
|
||||
" unix_socket=\"/run/mysqld/mysqld.sock\",\n",
|
||||
" database=\"LittleLemonDB\",\n",
|
||||
" use_pure=False,\n",
|
||||
" autocommit=True,\n",
|
||||
")\n",
|
||||
"assert isinstance(connection, CMySQLConnection)"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "markdown",
|
||||
"id": "19e74d2d-2b40-4a1b-a57e-38f27106220b",
|
||||
"metadata": {},
|
||||
"source": [
|
||||
"## Task 2"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "code",
|
||||
"execution_count": 3,
|
||||
"id": "1b386dae-78e4-44db-90e5-6da378de16fe",
|
||||
"metadata": {},
|
||||
"outputs": [
|
||||
{
|
||||
"name": "stdout",
|
||||
"output_type": "stream",
|
||||
"text": [
|
||||
"Tables:\n",
|
||||
" Addresses\n",
|
||||
" Bookings\n",
|
||||
" Customers\n",
|
||||
" Employees\n",
|
||||
" MenuItems\n",
|
||||
" OrderItems\n",
|
||||
" Orders\n"
|
||||
]
|
||||
}
|
||||
],
|
||||
"source": [
|
||||
"try:\n",
|
||||
" with connection.cursor() as cursor:\n",
|
||||
" assert isinstance(cursor, CMySQLCursor)\n",
|
||||
"\n",
|
||||
" _ = cursor.execute(\"show tables\")\n",
|
||||
" print(\"Tables:\")\n",
|
||||
" for (table_name,) in cursor:\n",
|
||||
" print(f\" {table_name}\")\n",
|
||||
"except Error as err:\n",
|
||||
" print(err)"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "markdown",
|
||||
"id": "62e2485b-1391-4fc6-aa73-35d0ebd8e95d",
|
||||
"metadata": {},
|
||||
"source": [
|
||||
"## Task 3\n",
|
||||
"**SQL query in `sql/promotional_campaign.sql`:**\n",
|
||||
"```sql\n",
|
||||
"select\n",
|
||||
" C.FirstName,\n",
|
||||
" C.LastName,\n",
|
||||
" C.PhoneNumber,\n",
|
||||
" C.EmailAddress,\n",
|
||||
" max(O.BillAmount) as MaxBillAmount\n",
|
||||
"from Orders as O\n",
|
||||
"inner join Bookings as B on O.BookingID = B.BookingID\n",
|
||||
"inner join Customers as C on B.CustomerID = C.CustomerID\n",
|
||||
"group by C.CustomerID\n",
|
||||
"having MaxBillAmount > 60.00;\n",
|
||||
"```"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "code",
|
||||
"execution_count": 4,
|
||||
"id": "214d0b0e-dd5b-4113-b6d7-aca020655ef3",
|
||||
"metadata": {},
|
||||
"outputs": [
|
||||
{
|
||||
"name": "stdout",
|
||||
"output_type": "stream",
|
||||
"text": [
|
||||
"\n",
|
||||
"Customers that placed an order greater then 60.00€:\n",
|
||||
" Li Wei Zhang\n",
|
||||
" Minimum bill amount: 82.50€\n",
|
||||
" Phone number: +86123456789\n",
|
||||
" Email address: li.wei.zhang@example.com\n",
|
||||
" Ivanov Petrov\n",
|
||||
" Minimum bill amount: 150.50€\n",
|
||||
" Phone number: +70987654321\n",
|
||||
" Email address: ivanov.petrov@example.com\n"
|
||||
]
|
||||
}
|
||||
],
|
||||
"source": [
|
||||
"with open(\"./sql/promotional_campaign.sql\") as promo_campaign_file:\n",
|
||||
" promo_campain_request = promo_campaign_file.read()\n",
|
||||
" \n",
|
||||
"try:\n",
|
||||
" with connection.cursor() as cursor:\n",
|
||||
" assert isinstance(cursor, CMySQLCursor)\n",
|
||||
" _ = cursor.execute(promo_campain_request)\n",
|
||||
"\n",
|
||||
" print()\n",
|
||||
"\n",
|
||||
" print(\"Customers that placed an order greater then 60.00€:\")\n",
|
||||
" for (\n",
|
||||
" first_name,\n",
|
||||
" last_name,\n",
|
||||
" phone_number,\n",
|
||||
" email_address,\n",
|
||||
" min_bill_amount,\n",
|
||||
" ) in cursor:\n",
|
||||
" assert isinstance(first_name, str)\n",
|
||||
" assert isinstance(last_name, str)\n",
|
||||
" assert isinstance(phone_number, str)\n",
|
||||
" assert isinstance(email_address, str | None)\n",
|
||||
" assert isinstance(min_bill_amount, Decimal)\n",
|
||||
" print(f\" {first_name} {last_name}\")\n",
|
||||
" print(f\" Minimum bill amount: {min_bill_amount}€\")\n",
|
||||
" print(f\" Phone number: {phone_number}\")\n",
|
||||
" if email_address:\n",
|
||||
" print(f\" Email address: {email_address}\")\n",
|
||||
"except Error as err:\n",
|
||||
" print(err)"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "markdown",
|
||||
"id": "be3c702d-5ab6-47a6-a19b-4e26aefdbd6e",
|
||||
"metadata": {},
|
||||
"source": [
|
||||
"## Cleanup"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "code",
|
||||
"execution_count": 5,
|
||||
"id": "e7f0a6dc-4940-4f8b-a89c-e714e9d375ba",
|
||||
"metadata": {},
|
||||
"outputs": [],
|
||||
"source": [
|
||||
"connection.close()"
|
||||
]
|
||||
}
|
||||
],
|
||||
"metadata": {
|
||||
"kernelspec": {
|
||||
"display_name": "Python 3 (ipykernel)",
|
||||
"language": "python",
|
||||
"name": "python3"
|
||||
},
|
||||
"language_info": {
|
||||
"codemirror_mode": {
|
||||
"name": "ipython",
|
||||
"version": 3
|
||||
},
|
||||
"file_extension": ".py",
|
||||
"mimetype": "text/x-python",
|
||||
"name": "python",
|
||||
"nbconvert_exporter": "python",
|
||||
"pygments_lexer": "ipython3",
|
||||
"version": "3.13.0"
|
||||
}
|
||||
},
|
||||
"nbformat": 4,
|
||||
"nbformat_minor": 5
|
||||
}
|
||||
19
pyproject.toml
Normal file
@@ -0,0 +1,19 @@
|
||||
[tool.sqlfluff.core]
|
||||
dialiact = "mysql"
|
||||
max_line_length = 110
|
||||
exclude_rules = "ST06"
|
||||
|
||||
[tool.sqlfluff.rules.capitalisation.keywords]
|
||||
capitalisation_policy = "lower"
|
||||
|
||||
[tool.sqlfluff.rules.capitalisation.identifiers]
|
||||
extended_capitalisation_policy = "pascal"
|
||||
|
||||
[tool.sqlfluff.rules.capitalisation.types]
|
||||
extended_capitalisation_policy = "lower"
|
||||
|
||||
[tool.sqlfluff.rules.references.keywords]
|
||||
ignore_words = "role"
|
||||
|
||||
[tool.sqlfluff.indentation]
|
||||
allow_implicit_indents = true
|
||||
15
sql/add_booking.sql
Normal file
@@ -0,0 +1,15 @@
|
||||
-- modify bookings - task 1
|
||||
-- changes:
|
||||
-- changed BookingDate (Reserved) data type from date to datetime, because I assumed that Little Lemon
|
||||
-- allows wants bookings per day and table - a table is considered blocked for 2 hours
|
||||
-- added EmployeeID input parameter
|
||||
-- noqa: disable=CP03,LT02,RF03
|
||||
create procedure AddBooking (
|
||||
in BookingID int, in Reserved datetime, in TableNumber int, in CustomerID int, in EmployeeID int
|
||||
)
|
||||
begin
|
||||
insert into Bookings (BookingID, Reserved, TableNumber, CustomerID, EmployeeID) values (
|
||||
BookingID, Reserved, TableNumber, CustomerID, EmployeeID
|
||||
);
|
||||
select concat("New booking added") as Confirmation;
|
||||
end
|
||||
30
sql/add_valid_booking.sql
Normal file
@@ -0,0 +1,30 @@
|
||||
-- available bookings - task 3
|
||||
-- changes:
|
||||
-- changed BookingDate (Reserved) data type from date to datetime, because I assumed that Little Lemon
|
||||
-- allows wants bookings per day and table - a table is considered blocked for 2 hours
|
||||
-- added CustomerID and EmployeeID input parameters
|
||||
-- noqa: disable=CP03,LT02,RF03
|
||||
--
|
||||
create procedure AddValidBooking (
|
||||
in Reserved datetime, in TableNumber int, in CustomerID int, in EmployeeID int
|
||||
)
|
||||
begin
|
||||
start transaction;
|
||||
|
||||
if TableIsFree(Reserved, TableNumber) then
|
||||
insert into Bookings (Reserved, TableNumber, CustomerID, EmployeeID) values (
|
||||
Reserved, TableNumber, CustomerID, EmployeeID
|
||||
);
|
||||
commit;
|
||||
select concat(
|
||||
"Table ", TableNumber,
|
||||
" was free - booking accepted (BookingID=", (select last_insert_id()), ')'
|
||||
) as BookingStatus;
|
||||
else
|
||||
rollback;
|
||||
select concat(
|
||||
"Table ", TableNumber,
|
||||
" is already booked - booking cancelled"
|
||||
) as BookingStatus;
|
||||
end if;
|
||||
end
|
||||
97
sql/available_booking_results.txt
Normal file
@@ -0,0 +1,97 @@
|
||||
# Task 1
|
||||
> source ./example_bookings.sql
|
||||
> select * from `Bookings` where `BookingID` between 11 and 14
|
||||
+-----------+---------------------+-------------+------------+------------+
|
||||
| BookingID | Reserved | TableNumber | CustomerID | EmployeeID |
|
||||
+-----------+---------------------+-------------+------------+------------+
|
||||
| 11 | 2022-10-14 18:00:00 | 5 | 1 | 1 |
|
||||
| 12 | 2022-11-12 19:30:00 | 3 | 3 | 1 |
|
||||
| 13 | 2022-10-11 18:45:00 | 2 | 2 | 1 |
|
||||
| 14 | 2022-10-13 19:15:00 | 2 | 1 | 1 |
|
||||
+-----------+---------------------+-------------+------------+------------+
|
||||
|
||||
# Task 2
|
||||
> delimiter $
|
||||
> source ./table_is_free.sql
|
||||
> source ./check_booking.sql
|
||||
> delimiter ;
|
||||
> call CheckBooking("2022-11-12 18:15:00", 3, @IsFree);
|
||||
+---------------------------+
|
||||
| BookingStatus |
|
||||
+---------------------------+
|
||||
| Table 3 is already booked |
|
||||
+---------------------------+
|
||||
> select @IsFree;
|
||||
+---------+
|
||||
| @IsFree |
|
||||
+---------+
|
||||
| 0 |
|
||||
+---------+
|
||||
> call CheckBooking("2022-11-12 17:15:00", 3, @IsFree);
|
||||
+-----------------+
|
||||
| BookingStatus |
|
||||
+-----------------+
|
||||
| Table 3 is free |
|
||||
+-----------------+
|
||||
> select @IsFree;
|
||||
+---------+
|
||||
| @IsFree |
|
||||
+---------+
|
||||
| 1 |
|
||||
+---------+
|
||||
|
||||
# Task 3
|
||||
> delimiter $
|
||||
> source ./add_valid_booking.sql
|
||||
> delimiter ;
|
||||
> call AddValidBooking("2022-11-12 18:15:00", 3, 4, 1);
|
||||
+-----------------------------------------------+
|
||||
| BookingStatus |
|
||||
+-----------------------------------------------+
|
||||
| Table 3 is already booked - booking cancelled |
|
||||
+-----------------------------------------------+
|
||||
> select * from `Bookings`
|
||||
+-----------+---------------------+-------------+------------+------------+
|
||||
| BookingID | Reserved | TableNumber | CustomerID | EmployeeID |
|
||||
+-----------+---------------------+-------------+------------+------------+
|
||||
| 1 | 2024-11-14 18:00:00 | 1 | 3 | 1 |
|
||||
| 2 | 2024-11-14 19:30:00 | 2 | 2 | 1 |
|
||||
| 3 | 2024-11-14 18:45:00 | 3 | 4 | 1 |
|
||||
| 4 | 2024-11-14 19:15:00 | 4 | 1 | 2 |
|
||||
| 5 | 2024-11-14 18:30:00 | 5 | 6 | 2 |
|
||||
| 6 | 2024-11-14 19:00:00 | 6 | 5 | 2 |
|
||||
| 7 | 2024-11-15 18:15:00 | 1 | 7 | 5 |
|
||||
| 8 | 2024-11-15 19:45:00 | 2 | 8 | 5 |
|
||||
| 9 | 2024-11-15 18:30:00 | 3 | 9 | 2 |
|
||||
| 10 | 2024-11-15 19:00:00 | 4 | 10 | 5 |
|
||||
| 11 | 2022-10-14 18:00:00 | 5 | 1 | 1 |
|
||||
| 12 | 2022-11-12 19:30:00 | 3 | 3 | 1 |
|
||||
| 13 | 2022-10-11 18:45:00 | 2 | 2 | 1 |
|
||||
| 14 | 2022-10-13 19:15:00 | 2 | 1 | 1 |
|
||||
+-----------+---------------------+-------------+------------+------------+
|
||||
> call AddValidBooking("2022-11-12 17:15:00", 3, 4, 1);
|
||||
+----------------------------------------------------+
|
||||
| BookingStatus |
|
||||
+----------------------------------------------------+
|
||||
| Table 3 was free - booking accepted (BookingID=15) |
|
||||
+----------------------------------------------------+
|
||||
> select * from `Bookings`
|
||||
+-----------+---------------------+-------------+------------+------------+
|
||||
| BookingID | Reserved | TableNumber | CustomerID | EmployeeID |
|
||||
+-----------+---------------------+-------------+------------+------------+
|
||||
| 1 | 2024-11-14 18:00:00 | 1 | 3 | 1 |
|
||||
| 2 | 2024-11-14 19:30:00 | 2 | 2 | 1 |
|
||||
| 3 | 2024-11-14 18:45:00 | 3 | 4 | 1 |
|
||||
| 4 | 2024-11-14 19:15:00 | 4 | 1 | 2 |
|
||||
| 5 | 2024-11-14 18:30:00 | 5 | 6 | 2 |
|
||||
| 6 | 2024-11-14 19:00:00 | 6 | 5 | 2 |
|
||||
| 7 | 2024-11-15 18:15:00 | 1 | 7 | 5 |
|
||||
| 8 | 2024-11-15 19:45:00 | 2 | 8 | 5 |
|
||||
| 9 | 2024-11-15 18:30:00 | 3 | 9 | 2 |
|
||||
| 10 | 2024-11-15 19:00:00 | 4 | 10 | 5 |
|
||||
| 11 | 2022-10-14 18:00:00 | 5 | 1 | 1 |
|
||||
| 12 | 2022-11-12 19:30:00 | 3 | 3 | 1 |
|
||||
| 13 | 2022-10-11 18:45:00 | 2 | 2 | 1 |
|
||||
| 14 | 2022-10-13 19:15:00 | 2 | 1 | 1 |
|
||||
| 15 | 2022-11-12 17:15:00 | 3 | 4 | 1 |
|
||||
+-----------+---------------------+-------------+------------+------------+
|
||||
13
sql/cancel_booking.sql
Normal file
@@ -0,0 +1,13 @@
|
||||
-- modify bookings - task 3
|
||||
-- add and update bookings - task 3
|
||||
-- noqa: disable=CP03,LT02,RF03
|
||||
create procedure CancelBooking (in BookingID int)
|
||||
begin
|
||||
delete from Bookings as B
|
||||
where B.BookingID = BookingID;
|
||||
if row_count() = 1 then
|
||||
select concat("Booking ", BookingID, " cancelled") as Confirmation;
|
||||
else
|
||||
select concat("Booking ", BookingID, " not cancelled - missing booking") as Confirmation;
|
||||
end if;
|
||||
end
|
||||
9
sql/cancel_order.sql
Normal file
@@ -0,0 +1,9 @@
|
||||
-- query optimization - task 3
|
||||
-- noqa: disable=CP03
|
||||
create procedure CancelOrder (in TargetOrderID int)
|
||||
begin
|
||||
delete from Orders
|
||||
where OrderID = TargetOrderID;
|
||||
|
||||
select concat("Order ", TargetOrderID, if(row_count() = 1, " is cancelled", " doesn't exist")) as Confirmation;
|
||||
end
|
||||
10
sql/check_booking.sql
Normal file
@@ -0,0 +1,10 @@
|
||||
-- available bookings - task 2
|
||||
-- changes:
|
||||
-- changed BookingDate (Reserved) data type from date to datetime, because I assumed that Little Lemon
|
||||
-- allows wants bookings per day and table - a table is considered blocked for 2 hours
|
||||
-- noqa: disable=CP03,LT02,RF03
|
||||
create procedure CheckBooking (in Reserved datetime, in TableNumber int, out IsFree boolean) --
|
||||
begin
|
||||
set IsFree = TableIsFree(Reserved, TableNumber);
|
||||
select concat("Table ", TableNumber, " is ", if(IsFree, "free", "already booked")) as BookingStatus;
|
||||
end
|
||||
15
sql/create_orders_view.sql
Normal file
@@ -0,0 +1,15 @@
|
||||
-- sales report - task 1
|
||||
-- changes:
|
||||
-- interpreted quantity as the number of ordered items, because I assumed that Little lemon wants
|
||||
-- orders à la carte instead of fixed menus
|
||||
drop view if exists OrdersView;
|
||||
|
||||
create view OrdersView as
|
||||
select
|
||||
O.OrderID,
|
||||
count(OI.MenuItemID) as Quantity,
|
||||
O.BillAmount as Cost
|
||||
from Orders as O
|
||||
inner join OrderItems as OI on O.OrderID = OI.OrderID
|
||||
group by O.OrderID
|
||||
having Quantity > 2;
|
||||
12
sql/example_bookings.sql
Normal file
@@ -0,0 +1,12 @@
|
||||
-- available bookings - task 1
|
||||
-- changes:
|
||||
-- changed BookingDate (Reserved) data type from date to datetime, because I assumed that Little Lemon
|
||||
-- allows wants bookings per day and table - a table is considered blocked for 2 hours
|
||||
-- changed BookingID range from 1-4 to 11-14, because there are already 10 Bookings in my test data set
|
||||
-- added arbitrary EmployeeID that corresponds to the Employee that handled the booking process
|
||||
-- noqa: disable=CP03
|
||||
insert into Bookings (BookingID, Reserved, TableNumber, CustomerID, EmployeeID) values
|
||||
(11, '2022-10-14 18:00:00', 5, 1, 1),
|
||||
(12, '2022-11-12 19:30:00', 3, 3, 1),
|
||||
(13, '2022-10-11 18:45:00', 2, 2, 1),
|
||||
(14, '2022-10-13 19:15:00', 2, 1, 1);
|
||||
47
sql/get_expensive_orders.sql
Normal file
@@ -0,0 +1,47 @@
|
||||
-- sales report - task 2
|
||||
-- changes:
|
||||
-- removed menu name, because I assumed that Little lemon wants orders à la carte instead of fixed menus
|
||||
-- changed cost cutoff from 150.00 to 75.00, because I wanted more than one test result
|
||||
with
|
||||
GroupedOrderItems as (
|
||||
select
|
||||
OI.OrderID,
|
||||
MI.Category,
|
||||
concat(MI.Name, " (", count(OI.OrderItemID), "x)") as Item
|
||||
from OrderItems as OI
|
||||
inner join MenuItems as MI on OI.MenuItemID = MI.MenuItemID
|
||||
group by OI.OrderID, MI.Category, OI.MenuItemID
|
||||
),
|
||||
|
||||
MainOrderItems as (
|
||||
select
|
||||
OrderID,
|
||||
group_concat(Item separator '\n') as Items
|
||||
from GroupedOrderItems
|
||||
where Category = "Main"
|
||||
group by OrderID
|
||||
),
|
||||
|
||||
StarterOrderItems as (
|
||||
select
|
||||
OrderID,
|
||||
group_concat(Item separator '\n') as Items
|
||||
from GroupedOrderItems
|
||||
where Category = "Starter"
|
||||
group by OrderID
|
||||
)
|
||||
|
||||
select
|
||||
C.CustomerID,
|
||||
concat(C.FirstName, " ", C.LastName) as FullName,
|
||||
O.OrderID,
|
||||
O.BillAmount as Cost,
|
||||
coalesce(MOI.Items, "") as Mains,
|
||||
coalesce(SOI.Items, "") as Starters
|
||||
from Orders as O
|
||||
inner join Bookings as B on O.BookingID = B.BookingID
|
||||
inner join Customers as C on B.CustomerID = C.CustomerID
|
||||
left join MainOrderItems as MOI on O.OrderID = MOI.OrderID
|
||||
left join StarterOrderItems as SOI on O.OrderID = SOI.OrderID
|
||||
where O.BillAmount > 75.00
|
||||
group by O.OrderID;
|
||||
12
sql/get_max_quantity.sql
Normal file
@@ -0,0 +1,12 @@
|
||||
-- query optimization - task 1
|
||||
-- changes:
|
||||
-- interpreted quantity as the number of items in an order, because I assumed that Little lemon wants
|
||||
-- orders à la carte instead of fixed menus
|
||||
|
||||
create procedure GetMaxQuantity () -- noqa: disable=CP03
|
||||
select count(OI.OrderItemID) as MaxQuantityInOrder
|
||||
from MenuItems as MI
|
||||
inner join OrderItems as OI on MI.MenuItemID = OI.MenuItemID
|
||||
group by OI.OrderID
|
||||
order by MaxQuantityInOrder desc
|
||||
limit 1
|
||||
15
sql/get_order_detail.sql
Normal file
@@ -0,0 +1,15 @@
|
||||
-- query optimization - task 2
|
||||
-- changes:
|
||||
-- interpreted quantity as the number of items in an order, because I assumed that Little lemon wants
|
||||
-- orders à la carte instead of fixed menus
|
||||
|
||||
prepare GetOrderDetail from "
|
||||
select
|
||||
O.OrderID,
|
||||
count(OI.MenuItemID) as Quantity,
|
||||
O.BillAmount as Cost
|
||||
from Orders as O
|
||||
inner join OrderItems as OI on O.OrderID = OI.OrderID
|
||||
inner join Bookings as B on O.BookingID = B.BookingID
|
||||
where B.CustomerID = ?;
|
||||
";
|
||||
11
sql/get_popular_menu_items.sql
Normal file
@@ -0,0 +1,11 @@
|
||||
-- sales report - task 3
|
||||
-- changes:
|
||||
-- replaced menu name with menu item name, because I assumed that Little lemon wants orders à la carte
|
||||
-- instead of fixed menus
|
||||
select
|
||||
MI.Name,
|
||||
count(OI.OrderItemID) as OrderQuantity
|
||||
from MenuItems as MI
|
||||
inner join OrderItems as OI on MI.MenuItemID = OI.MenuItemID
|
||||
group by OI.MenuItemID
|
||||
having OrderQuantity > 2;
|
||||
126
sql/init_data.sql
Normal file
@@ -0,0 +1,126 @@
|
||||
delete from MenuItems;
|
||||
insert into MenuItems (MenuItemID, Name, Category, Price) values
|
||||
(1, "Grilled Artichokes", "Starter", 6.00),
|
||||
(2, "Lentil Soup", "Starter", 7.00),
|
||||
(3, "Humus Plate", "Starter", 6.00),
|
||||
(4, "Eggplant Bruschetta", "Starter", 7.00),
|
||||
(5, "Gigantes Plaki", "Main", 14.00),
|
||||
(6, "Minestrone", "Main", 16.00),
|
||||
(7, "Moussaka", "Main", 17.00),
|
||||
(8, "Pasta alla Norma", "Main", 12.00),
|
||||
(9, "Tabbouleh", "Salad", 8.00),
|
||||
(10, "Green Bean Salad", "Salad", 8.00),
|
||||
(11, "Tomato Salad", "Salad", 9.50),
|
||||
(12, "Fennel Salad", "Salad", 8.50),
|
||||
(13, "Fruit Salad", "Desert", 7.00),
|
||||
(14, "Roasted Grapes", "Desert", 6.50),
|
||||
(15, "Grilled Mango", "Desert", 8.50),
|
||||
(16, "Grilled Waterlemon", "Desert", 8.50);
|
||||
|
||||
delete from Addresses;
|
||||
insert into Addresses (AddressID, Street, PostalCode, City, Country) values
|
||||
(1, 'Hauptstraße 1', '10115', 'Berlin', 'Germany'),
|
||||
(2, 'Friedrichstraße 56', '10119', 'Berlin', 'Germany'),
|
||||
(3, 'Kurfürstenstraße 135', '10115', 'Berlin', 'Germany'),
|
||||
(4, 'Altenhofen 168', '10623', 'Berlin', 'Germany'),
|
||||
(5, 'Hauptstraße 180', '10116', 'Berlin', 'Germany');
|
||||
|
||||
delete from Employees;
|
||||
insert into Employees (
|
||||
EmployeeID, FirstName, LastName, PhoneNumber, EmailAddress, Role, AnnualSalary, AddressID
|
||||
) values
|
||||
(1, 'Mario', 'Gollini', '+4915123456789', 'mario.gollini@littlelemon.de', 'Manager', 72383.00, 1),
|
||||
(2, 'Adrian', 'Gollini', '+4916198765432', 'adrian.gollini@littlelemon.de', 'Receptionist', 74083.00, 2),
|
||||
(3, 'Giorgos', 'Dioudis', '+4917654321098', 'giogos.dioudis@littlelemon.de', 'Assistant Chef', 77912.00, 3),
|
||||
(4, 'Fatma', 'Kaya', '+4918765432190', 'fatma.kaya@littlelemon.de', 'Head Chef', 79314.00, 4),
|
||||
(5, 'Elena', 'Salvai', '+4919876543210', 'elena.salvai@littlelemon.de', 'Waiter', 78921.00, 5);
|
||||
|
||||
delete from Customers;
|
||||
insert into Customers (
|
||||
CustomerID, FirstName, LastName, PhoneNumber, EmailAddress, AddressID
|
||||
)
|
||||
values
|
||||
(1, 'Ahmed', 'Mohamed', '+20212345678', 'ahmed.mohamed@example.com', null),
|
||||
(2, 'Sophie', 'Dupont', '+33612345678', 'sophie.dupont@example.com', null),
|
||||
(3, 'Li Wei', 'Zhang', '+86123456789', 'li.wei.zhang@example.com', null),
|
||||
(4, 'Maria', 'Rodriguez', '+34612345678', 'maria.rodriguez@example.com', null),
|
||||
(5, 'Ivanov', 'Petrov', '+70987654321', 'ivanov.petrov@example.com', null),
|
||||
(6, 'José', 'Martinez', '+54987654321', 'jose.martinez@example.com', null),
|
||||
(7, 'Maria', 'Schmidt', '+49987654321', 'maria.schmidt@example.com', null),
|
||||
(8, 'Thomas', 'Müller', '+44987654321', 'thomas.mueller@example.com', null),
|
||||
(9, 'Ramón', 'García', '+58987654321', 'ramon.garcia@example.com', null),
|
||||
(10, 'Lee', 'Kim', '+82109876543', 'lee.kim@example.com', null);
|
||||
|
||||
delete from Bookings;
|
||||
insert into Bookings (BookingID, Reserved, TableNumber, CustomerID, EmployeeID)
|
||||
values
|
||||
(1, '2024-11-14 18:00:00', 1, 3, 1),
|
||||
(2, '2024-11-14 19:30:00', 2, 2, 1),
|
||||
(3, '2024-11-14 18:45:00', 3, 4, 1),
|
||||
(4, '2024-11-14 19:15:00', 4, 1, 2),
|
||||
(5, '2024-11-14 18:30:00', 5, 6, 2),
|
||||
(6, '2024-11-14 19:00:00', 6, 5, 2),
|
||||
(7, '2024-11-15 18:15:00', 1, 7, 5),
|
||||
(8, '2024-11-15 19:45:00', 2, 8, 5),
|
||||
(9, '2024-11-15 18:30:00', 3, 9, 2),
|
||||
(10, '2024-11-15 19:00:00', 4, 10, 5);
|
||||
|
||||
insert into Orders (OrderID, Started, Finished, BillAmount, BookingID)
|
||||
values
|
||||
(1, '2024-11-14 18:05:00', '2023-10-01 19:25:00', null, 1),
|
||||
(2, '2024-11-14 19:35:00', '2023-10-02 20:45:00', null, 2),
|
||||
(3, '2024-11-14 19:10:00', '2023-10-03 20:30:00', null, 3),
|
||||
(4, '2024-11-14 19:35:00', '2023-10-04 20:50:00', null, 4),
|
||||
(5, '2024-11-14 19:40:00', '2023-10-05 20:55:00', null, 5),
|
||||
(6, '2024-11-14 19:40:00', '2023-10-06 20:45:00', null, 6);
|
||||
|
||||
insert into OrderItems (OrderItemID, MenuItemID, OrderID, Ordered, Delivered, DeliveryStatus)
|
||||
values
|
||||
(1, 1, 1, '2024-11-14 18:05:00', '2024-11-14 18:25:00', 'Delivered'),
|
||||
(2, 2, 1, '2024-11-14 18:05:00', '2024-11-14 18:25:00', 'Delivered'),
|
||||
(3, 3, 1, '2024-11-14 18:05:00', '2024-11-14 18:25:00', 'Delivered'),
|
||||
(4, 5, 1, '2024-11-14 18:05:00', '2024-11-14 18:40:00', 'Delivered'),
|
||||
(5, 5, 1, '2024-11-14 18:05:00', '2024-11-14 18:40:00', 'Delivered'),
|
||||
(6, 8, 1, '2024-11-14 18:05:00', '2024-11-14 18:40:00', 'Delivered'),
|
||||
(7, 14, 1, '2024-11-14 18:05:00', '2024-11-14 19:05:00', 'Delivered'),
|
||||
(8, 15, 1, '2024-11-14 18:05:00', '2024-11-14 19:05:00', 'Delivered'),
|
||||
(9, 16, 1, '2024-11-14 18:05:00', '2024-11-14 19:05:00', 'Delivered'),
|
||||
(10, 2, 2, '2024-11-14 19:35:00', '2024-11-14 19:55:00', 'Delivered'),
|
||||
(11, 5, 2, '2024-11-14 19:35:00', '2024-11-14 20:10:00', 'Delivered'),
|
||||
(12, 13, 2, '2024-11-14 19:35:00', '2024-11-14 20:35:00', 'Delivered'),
|
||||
(13, 4, 3, '2024-11-14 19:10:00', '2024-11-14 19:30:00', 'Delivered'),
|
||||
(14, 7, 3, '2024-11-14 19:10:00', '2024-11-14 19:45:00', 'Delivered'),
|
||||
(15, 13, 3, '2024-11-14 19:10:00', '2024-11-14 20:10:00', 'Delivered'),
|
||||
(16, 3, 4, '2024-11-14 19:35:00', '2024-11-14 19:55:00', 'Delivered'),
|
||||
(17, 6, 4, '2024-11-14 19:35:00', '2024-11-14 20:10:00', 'Delivered'),
|
||||
(18, 13, 4, '2024-11-14 19:35:00', '2024-11-14 20:35:00', 'Delivered'),
|
||||
(19, 9, 5, '2024-11-14 19:40:00', '2024-11-14 20:00:00', 'Delivered'),
|
||||
(20, 8, 5, '2024-11-14 19:40:00', '2024-11-14 20:15:00', 'Delivered'),
|
||||
(22, 2, 6, '2024-11-14 19:40:00', '2024-11-14 19:55:00', 'Delivered'),
|
||||
(23, 4, 6, '2024-11-14 19:40:00', '2024-11-14 19:55:00', 'Delivered'),
|
||||
(24, 2, 6, '2024-11-14 19:40:00', '2024-11-14 19:55:00', 'Delivered'),
|
||||
(25, 3, 6, '2024-11-14 19:40:00', '2024-11-14 19:55:00', 'Delivered'),
|
||||
(26, 1, 6, '2024-11-14 19:40:00', '2024-11-14 19:55:00', 'Delivered'),
|
||||
(27, 6, 6, '2024-11-14 19:40:00', '2024-11-14 20:10:00', 'Delivered'),
|
||||
(28, 6, 6, '2024-11-14 19:40:00', '2024-11-14 20:10:00', 'Delivered'),
|
||||
(29, 5, 6, '2024-11-14 19:40:00', '2024-11-14 20:10:00', 'Delivered'),
|
||||
(30, 5, 6, '2024-11-14 19:40:00', '2024-11-14 20:10:00', 'Delivered'),
|
||||
(31, 7, 6, '2024-11-14 19:40:00', '2024-11-14 20:10:00', 'Delivered'),
|
||||
(32, 15, 6, '2024-11-14 19:40:00', '2024-11-14 20:35:00', 'Delivered'),
|
||||
(33, 14, 6, '2024-11-14 19:40:00', '2024-11-14 20:35:00', 'Delivered'),
|
||||
(34, 15, 6, '2024-11-14 19:40:00', '2024-11-14 20:35:00', 'Delivered'),
|
||||
(35, 16, 6, '2024-11-14 19:40:00', '2024-11-14 20:35:00', 'Delivered'),
|
||||
(36, 16, 6, '2024-11-14 19:40:00', '2024-11-14 20:35:00', 'Delivered');
|
||||
|
||||
update Orders as O
|
||||
inner join
|
||||
(
|
||||
select
|
||||
OI.OrderID,
|
||||
sum(MI.Price) as TotalItemPrice
|
||||
from OrderItems as OI
|
||||
inner join MenuItems as MI on OI.MenuItemID = MI.MenuItemID
|
||||
group by OI.OrderID
|
||||
) as A
|
||||
on O.OrderID = A.OrderID
|
||||
set O.BillAmount = A.TotalItemPrice;
|
||||
101
sql/modify_bookings_results.txt
Normal file
@@ -0,0 +1,101 @@
|
||||
# Task 1
|
||||
> delimiter $
|
||||
> source ./add_booking.sql
|
||||
> delimiter ;
|
||||
> call AddBooking(20, "2024-11-19 19:00:00", 3, 1, 2)
|
||||
+-------------------+
|
||||
| Confirmation |
|
||||
+-------------------+
|
||||
| New booking added |
|
||||
+-------------------+
|
||||
> select * from `Bookings` where `BookingID` = 20
|
||||
+-----------+---------------------+-------------+------------+------------+
|
||||
| BookingID | Reserved | TableNumber | CustomerID | EmployeeID |
|
||||
+-----------+---------------------+-------------+------------+------------+
|
||||
| 20 | 2024-11-19 19:00:00 | 3 | 1 | 2 |
|
||||
+-----------+---------------------+-------------+------------+------------+
|
||||
|
||||
# Task 2
|
||||
> delimiter $
|
||||
> source ./update_booking.sql
|
||||
> delimiter ;
|
||||
> call UpdateBooking(20, date_sub((select Reserved from `Bookings` where `BookingID` = 20), interval 1 day))
|
||||
+--------------------+
|
||||
| Confirmation |
|
||||
+--------------------+
|
||||
| Booking 20 updated |
|
||||
+--------------------+
|
||||
> select * from `Bookings` where `BookingID` = 20;
|
||||
+-----------+---------------------+-------------+------------+------------+
|
||||
| BookingID | Reserved | TableNumber | CustomerID | EmployeeID |
|
||||
+-----------+---------------------+-------------+------------+------------+
|
||||
| 20 | 2024-11-18 19:00:00 | 3 | 1 | 2 |
|
||||
+-----------+---------------------+-------------+------------+------------+
|
||||
> call UpdateBooking(21, "2024-11-18 15:00:00")
|
||||
+---------------------------------------------+
|
||||
| Confirmation |
|
||||
+---------------------------------------------+
|
||||
| Booking 21 wasn't updated - missing booking |
|
||||
+---------------------------------------------+
|
||||
> select * from `Bookings` where `BookingID` = 21
|
||||
+-----------+----------+-------------+------------+------------+
|
||||
| BookingID | Reserved | TableNumber | CustomerID | EmployeeID |
|
||||
+-----------+----------+-------------+------------+------------+
|
||||
+-----------+----------+-------------+------------+------------+
|
||||
|
||||
# Task 3
|
||||
> delimiter $
|
||||
> source ./cancel_booking.sql
|
||||
> delimiter ;
|
||||
> call CancelBooking(20)
|
||||
+----------------------+
|
||||
| Confirmation |
|
||||
+----------------------+
|
||||
| Booking 20 cancelled |
|
||||
+----------------------+
|
||||
> select * from `Bookings`
|
||||
+-----------+---------------------+-------------+------------+------------+
|
||||
| BookingID | Reserved | TableNumber | CustomerID | EmployeeID |
|
||||
+-----------+---------------------+-------------+------------+------------+
|
||||
| 1 | 2024-11-14 18:00:00 | 1 | 3 | 1 |
|
||||
| 2 | 2024-11-14 19:30:00 | 2 | 2 | 1 |
|
||||
| 3 | 2024-11-14 18:45:00 | 3 | 4 | 1 |
|
||||
| 4 | 2024-11-14 19:15:00 | 4 | 1 | 2 |
|
||||
| 5 | 2024-11-14 18:30:00 | 5 | 6 | 2 |
|
||||
| 6 | 2024-11-14 19:00:00 | 6 | 5 | 2 |
|
||||
| 7 | 2024-11-15 18:15:00 | 1 | 7 | 5 |
|
||||
| 8 | 2024-11-15 19:45:00 | 2 | 8 | 5 |
|
||||
| 9 | 2024-11-15 18:30:00 | 3 | 9 | 2 |
|
||||
| 10 | 2024-11-15 19:00:00 | 4 | 10 | 5 |
|
||||
| 11 | 2022-10-14 18:00:00 | 5 | 1 | 1 |
|
||||
| 12 | 2022-11-12 19:30:00 | 3 | 3 | 1 |
|
||||
| 13 | 2022-10-11 18:45:00 | 2 | 2 | 1 |
|
||||
| 14 | 2022-10-13 19:15:00 | 2 | 1 | 1 |
|
||||
| 15 | 2022-11-12 17:15:00 | 3 | 4 | 1 |
|
||||
+-----------+---------------------+-------------+------------+------------+
|
||||
> call CancelBooking(21)
|
||||
+--------------------------------------------+
|
||||
| Confirmation |
|
||||
+--------------------------------------------+
|
||||
| Booking 21 not cancelled - missing booking |
|
||||
+--------------------------------------------+
|
||||
> select * from `Bookings`
|
||||
+-----------+---------------------+-------------+------------+------------+
|
||||
| BookingID | Reserved | TableNumber | CustomerID | EmployeeID |
|
||||
+-----------+---------------------+-------------+------------+------------+
|
||||
| 1 | 2024-11-14 18:00:00 | 1 | 3 | 1 |
|
||||
| 2 | 2024-11-14 19:30:00 | 2 | 2 | 1 |
|
||||
| 3 | 2024-11-14 18:45:00 | 3 | 4 | 1 |
|
||||
| 4 | 2024-11-14 19:15:00 | 4 | 1 | 2 |
|
||||
| 5 | 2024-11-14 18:30:00 | 5 | 6 | 2 |
|
||||
| 6 | 2024-11-14 19:00:00 | 6 | 5 | 2 |
|
||||
| 7 | 2024-11-15 18:15:00 | 1 | 7 | 5 |
|
||||
| 8 | 2024-11-15 19:45:00 | 2 | 8 | 5 |
|
||||
| 9 | 2024-11-15 18:30:00 | 3 | 9 | 2 |
|
||||
| 10 | 2024-11-15 19:00:00 | 4 | 10 | 5 |
|
||||
| 11 | 2022-10-14 18:00:00 | 5 | 1 | 1 |
|
||||
| 12 | 2022-11-12 19:30:00 | 3 | 3 | 1 |
|
||||
| 13 | 2022-10-11 18:45:00 | 2 | 2 | 1 |
|
||||
| 14 | 2022-10-13 19:15:00 | 2 | 1 | 1 |
|
||||
| 15 | 2022-11-12 17:15:00 | 3 | 4 | 1 |
|
||||
+-----------+---------------------+-------------+------------+------------+
|
||||
11
sql/promotional_campaign.sql
Normal file
@@ -0,0 +1,11 @@
|
||||
select
|
||||
C.FirstName,
|
||||
C.LastName,
|
||||
C.PhoneNumber,
|
||||
C.EmailAddress,
|
||||
max(O.BillAmount) as MaxBillAmount
|
||||
from Orders as O
|
||||
inner join Bookings as B on O.BookingID = B.BookingID
|
||||
inner join Customers as C on B.CustomerID = C.CustomerID
|
||||
group by C.CustomerID
|
||||
having MaxBillAmount > 60.00;
|
||||
47
sql/query_optimization_results.txt
Normal file
@@ -0,0 +1,47 @@
|
||||
# Task 1
|
||||
> delimiter $
|
||||
> source ./get_max_quantity.sql
|
||||
> delimiter ;
|
||||
> call GetMaxQuantity();
|
||||
+--------------------+
|
||||
| MaxQuantityInOrder |
|
||||
+--------------------+
|
||||
| 15 |
|
||||
+--------------------+
|
||||
|
||||
# Task 2
|
||||
> source ./get_order_detail.sql
|
||||
> set @customerID = 1
|
||||
> execute GetOrderDetail using @customerID
|
||||
+---------+----------+-------+
|
||||
| OrderID | Quantity | Cost |
|
||||
+---------+----------+-------+
|
||||
| 4 | 3 | 29.00 |
|
||||
+---------+----------+-------+
|
||||
|
||||
# Task 3
|
||||
> delimiter $
|
||||
> source ./cancel_order.sql
|
||||
> delimiter ;
|
||||
> call CancelOrder(2)
|
||||
+----------------------+
|
||||
| Confirmation |
|
||||
+----------------------+
|
||||
| Order 2 is cancelled |
|
||||
+----------------------+
|
||||
> select * from `Orders`
|
||||
+---------+---------------------+---------------------+------------+-----------+
|
||||
| OrderID | Started | Finished | BillAmount | BookingID |
|
||||
+---------+---------------------+---------------------+------------+-----------+
|
||||
| 1 | 2024-11-14 18:05:00 | 2023-10-01 19:25:00 | 82.50 | 1 |
|
||||
| 3 | 2024-11-14 19:10:00 | 2023-10-03 20:30:00 | 31.00 | 3 |
|
||||
| 4 | 2024-11-14 19:35:00 | 2023-10-04 20:50:00 | 29.00 | 4 |
|
||||
| 5 | 2024-11-14 19:40:00 | 2023-10-05 20:55:00 | 20.00 | 5 |
|
||||
| 6 | 2024-11-14 19:40:00 | 2023-10-06 20:45:00 | 150.50 | 6 |
|
||||
+---------+---------------------+---------------------+------------+-----------+
|
||||
> call CancelOrder(2)
|
||||
+-----------------------+
|
||||
| Confirmation |
|
||||
+-----------------------+
|
||||
| Order 2 doesn't exist |
|
||||
+-----------------------+
|
||||
40
sql/sales_report_results.txt
Normal file
@@ -0,0 +1,40 @@
|
||||
# Task 1
|
||||
> source ./create_orders_view.sql
|
||||
> select * from OrdersView;
|
||||
+---------+----------+--------+
|
||||
| OrderID | Quantity | Cost |
|
||||
+---------+----------+--------+
|
||||
| 1 | 9 | 82.50 |
|
||||
| 2 | 3 | 28.00 |
|
||||
| 3 | 3 | 31.00 |
|
||||
| 4 | 3 | 29.00 |
|
||||
| 6 | 15 | 150.50 |
|
||||
+---------+----------+--------+
|
||||
|
||||
# Task 2
|
||||
> source ./get_expensive_orders.sql
|
||||
+------------+---------------+---------+--------+-----------------------+--------------------------+
|
||||
| CustomerID | FullName | OrderID | Cost | Mains | Starters |
|
||||
+------------+---------------+---------+--------+-----------------------+--------------------------+
|
||||
| 3 | Li Wei Zhang | 1 | 82.50 | Gigantes Plaki (2x) | Grilled Artichokes (1x) |
|
||||
| | | | | Pasta alla Norma (1x) | Lentil Soup (1x) |
|
||||
| | | | | | Humus Plate (1x) |
|
||||
| 5 | Ivanov Petrov | 6 | 150.50 | Minestrone (2x) | Lentil Soup (2x) |
|
||||
| | | | | Gigantes Plaki (2x) | Eggplant Bruschetta (1x) |
|
||||
| | | | | Moussaka (1x) | Humus Plate (1x) |
|
||||
| | | | | | Grilled Artichokes (1x) |
|
||||
+------------+---------------+---------+--------+-----------------------+--------------------------+
|
||||
|
||||
# Task 3
|
||||
> source ./get_popular_menu_items.sql
|
||||
+--------------------+---------------+
|
||||
| Name | OrderQuantity |
|
||||
+--------------------+---------------+
|
||||
| Lentil Soup | 4 |
|
||||
| Humus Plate | 3 |
|
||||
| Gigantes Plaki | 5 |
|
||||
| Minestrone | 3 |
|
||||
| Fruit Salad | 3 |
|
||||
| Grilled Mango | 3 |
|
||||
| Grilled Waterlemon | 3 |
|
||||
+--------------------+---------------+
|
||||
17
sql/table_is_free.sql
Normal file
@@ -0,0 +1,17 @@
|
||||
-- available bookings - task 2
|
||||
-- changes:
|
||||
-- changed BookingDate (Reserved) data type from date to datetime, because I assumed that Little Lemon
|
||||
-- allows wants bookings per day and table - a table is considered blocked for 2 hours
|
||||
-- noqa: disable=CP03,LT02,RF03
|
||||
create function TableIsFree(Reserved datetime, TableNumber int)
|
||||
returns boolean
|
||||
deterministic
|
||||
begin
|
||||
return (select not exists (
|
||||
select BookingID
|
||||
from Bookings as B
|
||||
where
|
||||
abs(timestampdiff(second, B.Reserved, Reserved)) < 2 * 60 * 60
|
||||
and B.TableNumber = TableNumber
|
||||
));
|
||||
end
|
||||
16
sql/update_booking.sql
Normal file
@@ -0,0 +1,16 @@
|
||||
-- modify bookings - task 2
|
||||
-- changes:
|
||||
-- changed BookingDate (Reserved) data type from date to datetime, because I assumed that Little Lemon
|
||||
-- allows wants bookings per day and table - a table is considered blocked for 2 hours
|
||||
-- noqa: disable=CP03,LT02,RF03
|
||||
create procedure UpdateBooking (in BookingID int, in Reserved datetime)
|
||||
begin
|
||||
update Bookings as B
|
||||
set B.Reserved = Reserved
|
||||
where B.BookingID = BookingID;
|
||||
if row_count() = 1 then
|
||||
select concat("Booking ", BookingID, " updated") as Confirmation;
|
||||
else
|
||||
select concat("Booking ", BookingID, " wasn't updated - missing booking") as Confirmation;
|
||||
end if;
|
||||
end
|
||||