Salon Booking Management Dipesh Suthar

You might also like

Download as pdf or txt
Download as pdf or txt
You are on page 1of 26

Salon Booking Management

Project for Database Systems


This project was created as term project for course: Database Systems – INFOA3 – WS 23/24 – Friday
17:20 PM.

Assignment is to create database model and database schema for topic of their own choosing.
Project should have these parts:

● Topic – short description of what described database is about.


● Conceptual and logical (relational) diagrams
● Commands for creating schema in PostgreSQL database and filling it with sample data
(CREATE TABLE, INSERT INTO)
● Sample queries in RA and SQL (24 in SQL, 10 in RA – commands can be same for RA and SQL).
Try to get as many different categories of queries as possible list at the end. There is no set
number of categories you need to do, but if you only do simple queries or queries of one
type, it will influence your project final grade.

Yellow parts should be changed (EXAMPLE DELETE ME) – white parts don’t.

For completed project – this document must be sent to email of your LAB teacher. Your tables and
sample data must also be created and filled into your assigned PostgreSQL database. Your
database should be able to run all your queries (https://psqlc.db.kii.pef.czu.cz/SQLCLient).

Topic
• This is a salon booking management system. The system allows customers to log in, make
bookings, manage their bookings, provide feedback, and make payments. Additionally, it includes
features for managing packages, resetting passwords, and adding packages to bookings. It seems to
be a comprehensive platform for both customers and salon staff to facilitate the entire booking
process and customer interactions.
Conceptual diagram

Loops discussion
- In this project there is no loop dangerous happening in any entity.
Logical diagram

Tables (schema)
Normal text in this chapter should be in sql comments – so it could be all copied, pasted and run in
sql query windows. For commenting one row use -- at start of row. For commenting paragraph use /*
text */

Tables schema list:


-- This script was generated by the ERD tool in pgAdmin 4.

-- Please log an issue at https://github.com/pgadmin-org/pgadmin4/issues/new/choose if you find


any bugs, including reproduction steps.

BEGIN;

CREATE TABLE IF NOT EXISTS public.customer

cu_id integer NOT NULL DEFAULT nextval('customer_cu_id_seq'::regclass),

name text COLLATE pg_catalog."default",


cu_mobile numeric(10, 0),

cu_email character varying(256) COLLATE pg_catalog."default",

CONSTRAINT customer_pkey PRIMARY KEY (cu_id)

);

CREATE TABLE IF NOT EXISTS public.bookings

booking_id integer NOT NULL DEFAULT nextval('bookings_booking_id_seq'::regclass),

login_id integer NOT NULL DEFAULT nextval('bookings_login_id_seq'::regclass),

shop_id integer NOT NULL DEFAULT nextval('bookings_shop_id_seq'::regclass),

booking_date character varying(256) COLLATE pg_catalog."default",

booking_time character varying(256) COLLATE pg_catalog."default",

CONSTRAINT pk_bookings PRIMARY KEY (booking_id)

);

CREATE TABLE IF NOT EXISTS public.customer_registration

customer_cu_id integer NOT NULL DEFAULT nextval('customer_cu_id_seq'::regclass),

registration_cu_id integer NOT NULL DEFAULT nextval('registration_cu_id_seq'::regclass)

);

CREATE TABLE IF NOT EXISTS public.feedback

feedback_id integer NOT NULL,

booking_id integer,

shop_id integer,

cu_name character varying(256) COLLATE pg_catalog."default",

feedback_description character varying(256) COLLATE pg_catalog."default",

feedback_rating character varying(256) COLLATE pg_catalog."default",

feedback_date date,

feedback_time character varying(256) COLLATE pg_catalog."default",


CONSTRAINT pk_feedback PRIMARY KEY (feedback_id),

CONSTRAINT uc_feedback_customer_id UNIQUE (cu_name, shop_id)

);

CREATE TABLE IF NOT EXISTS public.forgot_password

forgotpassword_id integer NOT NULL DEFAULT


nextval('forgot_password_forgotpassword_id_seq'::regclass),

login_id integer NOT NULL DEFAULT nextval('forgot_password_login_id_seq'::regclass),

registration_id integer NOT NULL DEFAULT nextval('forgot_password_registration_id_seq'::regclass),

user_email character varying(256) COLLATE pg_catalog."default",

shop_email character varying(256) COLLATE pg_catalog."default",

new_password character varying(256) COLLATE pg_catalog."default",

CONSTRAINT pk_forgot_password PRIMARY KEY (forgotpassword_id, login_id),

CONSTRAINT u_fk_forgot_password_login UNIQUE (login_id, registration_id),

CONSTRAINT uc_forgot_password_shop_email UNIQUE (shop_email),

CONSTRAINT uc_forgot_password_user_email UNIQUE (user_email)

);

CREATE TABLE IF NOT EXISTS public.login

login_id integer NOT NULL DEFAULT nextval('login_login_id_seq'::regclass),

registration_id integer NOT NULL DEFAULT nextval('login_registration_id_seq'::regclass),

user_email character varying(256) COLLATE pg_catalog."default",

user_password character varying(256) COLLATE pg_catalog."default",

forgot_password character varying(256) COLLATE pg_catalog."default",

shop_email character varying(256) COLLATE pg_catalog."default",

shop_password character varying(256) COLLATE pg_catalog."default",

CONSTRAINT pk_login PRIMARY KEY (login_id),

CONSTRAINT u_fk_login_registration UNIQUE (registration_id),

CONSTRAINT uc_login_shop_email UNIQUE (shop_email)


);

CREATE TABLE IF NOT EXISTS public.packages

package_id integer NOT NULL DEFAULT nextval('packages_package_id_seq'::regclass),

shop_id integer NOT NULL DEFAULT nextval('packages_shop_id_seq'::regclass),

booking_id integer NOT NULL DEFAULT nextval('packages_booking_id_seq'::regclass),

bookings_customer_number integer,

package_name character varying(256) COLLATE pg_catalog."default",

package_price numeric(7, 0),

hairstyles character varying(256) COLLATE pg_catalog."default",

CONSTRAINT pk_packages PRIMARY KEY (package_id),

CONSTRAINT u_fk_packages_bookings UNIQUE (booking_id, bookings_customer_number, shop_id)

);

CREATE TABLE IF NOT EXISTS public.payment

payment_id serial NOT NULL,

booking_id integer,

shop_id integer,

cu_name character varying(256) COLLATE pg_catalog."default",

payment_method character varying(256) COLLATE pg_catalog."default",

payment_accept_or_decline boolean,

CONSTRAINT pk_payment PRIMARY KEY (payment_id),

CONSTRAINT u_fk_payment_bookings UNIQUE (cu_name, shop_id),

CONSTRAINT uc_payment_booking_id UNIQUE (booking_id)

);

CREATE TABLE IF NOT EXISTS public.registration

registration_id integer NOT NULL DEFAULT nextval('registration_registration_id_seq'::regclass),


cu_id integer NOT NULL DEFAULT nextval('registration_cu_id_seq'::regclass),

name text COLLATE pg_catalog."default",

email character varying(256) COLLATE pg_catalog."default",

contact numeric(10, 0),

password character varying(256) COLLATE pg_catalog."default",

c_password character varying(256) COLLATE pg_catalog."default",

CONSTRAINT pk_registration PRIMARY KEY (registration_id),

CONSTRAINT u_fk_email UNIQUE (email)

);

CREATE TABLE IF NOT EXISTS public.shop

shop_id integer NOT NULL DEFAULT nextval('shop_shop_id_seq'::regclass),

registration_id integer NOT NULL DEFAULT nextval('shop_registration_id_seq'::regclass),

shop_name text COLLATE pg_catalog."default",

shop_number numeric(10, 0),

owner_email character varying(256) COLLATE pg_catalog."default",

package_name character varying(256) COLLATE pg_catalog."default",

shop_address character varying(256) COLLATE pg_catalog."default",

shop_description character varying(256) COLLATE pg_catalog."default",

CONSTRAINT pk_shop PRIMARY KEY (shop_id),

CONSTRAINT uc_shop_owner_email UNIQUE (owner_email),

CONSTRAINT uc_shop_packages UNIQUE (package_name)

);

CREATE TABLE IF NOT EXISTS public.stylist

stylist_id integer NOT NULL DEFAULT nextval('stylist_stylist_id_seq'::regclass),

booking_id integer,

shop_id integer NOT NULL DEFAULT nextval('stylist_shop_id_seq'::regclass),

stylist_name text COLLATE pg_catalog."default",


stylist_types character varying(256) COLLATE pg_catalog."default",

stylist_price numeric(5, 0)

);

CREATE TABLE IF NOT EXISTS public.login_registration

login_registration_id integer NOT NULL DEFAULT nextval('login_registration_id_seq'::regclass),

registration_registration_id integer NOT NULL DEFAULT


nextval('registration_registration_id_seq'::regclass)

);

CREATE TABLE IF NOT EXISTS public.forgot_password_login

forgot_password_user_email character varying(256) COLLATE pg_catalog."default",

login_user_email character varying(256) COLLATE pg_catalog."default"

);

CREATE TABLE IF NOT EXISTS public.feedback_bookings

feedback_booking_id integer,

bookings_booking_id integer NOT NULL DEFAULT nextval('bookings_booking_id_seq'::regclass)

);

CREATE TABLE IF NOT EXISTS public.customer_feedback

customer_name text COLLATE pg_catalog."default",

feedback_cu_name character varying(256) COLLATE pg_catalog."default"

);

ALTER TABLE IF EXISTS public.customer_registration

ADD FOREIGN KEY (customer_cu_id)


REFERENCES public.customer (cu_id) MATCH SIMPLE

ON UPDATE NO ACTION

ON DELETE NO ACTION

NOT VALID;

ALTER TABLE IF EXISTS public.customer_registration

ADD FOREIGN KEY (registration_cu_id)

REFERENCES public.registration (cu_id) MATCH SIMPLE

ON UPDATE NO ACTION

ON DELETE NO ACTION

NOT VALID;

ALTER TABLE IF EXISTS public.packages

ADD FOREIGN KEY (shop_id)

REFERENCES public.shop (shop_id) MATCH SIMPLE

ON UPDATE NO ACTION

ON DELETE NO ACTION

NOT VALID;

ALTER TABLE IF EXISTS public.packages

ADD FOREIGN KEY (booking_id)

REFERENCES public.bookings (booking_id) MATCH SIMPLE

ON UPDATE NO ACTION

ON DELETE NO ACTION

NOT VALID;

ALTER TABLE IF EXISTS public.payment


ADD CONSTRAINT booking_id FOREIGN KEY (booking_id)

REFERENCES public.bookings (booking_id) MATCH SIMPLE

ON UPDATE NO ACTION

ON DELETE NO ACTION

NOT VALID;

ALTER TABLE IF EXISTS public.shop

ADD FOREIGN KEY (registration_id)

REFERENCES public.registration (registration_id) MATCH SIMPLE

ON UPDATE NO ACTION

ON DELETE NO ACTION

NOT VALID;

ALTER TABLE IF EXISTS public.stylist

ADD FOREIGN KEY (shop_id)

REFERENCES public.shop (shop_id) MATCH SIMPLE

ON UPDATE NO ACTION

ON DELETE NO ACTION

NOT VALID;

ALTER TABLE IF EXISTS public.stylist

ADD FOREIGN KEY (booking_id)

REFERENCES public.packages (booking_id) MATCH SIMPLE

ON UPDATE NO ACTION

ON DELETE NO ACTION

NOT VALID;
ALTER TABLE IF EXISTS public.login_registration

ADD FOREIGN KEY (login_registration_id)

REFERENCES public.login (registration_id) MATCH SIMPLE

ON UPDATE NO ACTION

ON DELETE NO ACTION

NOT VALID;

ALTER TABLE IF EXISTS public.login_registration

ADD FOREIGN KEY (registration_registration_id)

REFERENCES public.registration (registration_id) MATCH SIMPLE

ON UPDATE NO ACTION

ON DELETE NO ACTION

NOT VALID;

ALTER TABLE IF EXISTS public.forgot_password_login

ADD FOREIGN KEY (forgot_password_user_email)

REFERENCES public.forgot_password (user_email) MATCH SIMPLE

ON UPDATE NO ACTION

ON DELETE NO ACTION

NOT VALID;

ALTER TABLE IF EXISTS public.forgot_password_login

ADD FOREIGN KEY (login_user_email)

REFERENCES public.login (user_email) MATCH SIMPLE

ON UPDATE NO ACTION

ON DELETE NO ACTION

NOT VALID;
ALTER TABLE IF EXISTS public.feedback_bookings

ADD FOREIGN KEY (feedback_booking_id)

REFERENCES public.feedback (booking_id) MATCH SIMPLE

ON UPDATE NO ACTION

ON DELETE NO ACTION

NOT VALID;

ALTER TABLE IF EXISTS public.feedback_bookings

ADD FOREIGN KEY (bookings_booking_id)

REFERENCES public.bookings (booking_id) MATCH SIMPLE

ON UPDATE NO ACTION

ON DELETE NO ACTION

NOT VALID;

ALTER TABLE IF EXISTS public.customer_feedback

ADD FOREIGN KEY (customer_name)

REFERENCES public.customer (name) MATCH SIMPLE

ON UPDATE NO ACTION

ON DELETE NO ACTION

NOT VALID;

ALTER TABLE IF EXISTS public.customer_feedback

ADD FOREIGN KEY (feedback_cu_name)

REFERENCES public.feedback (cu_name) MATCH SIMPLE

ON UPDATE NO ACTION

ON DELETE NO ACTION

NOT VALID;
END;

Queries
There should be at least 24 queries in SQL total. Each query should have:

● Query Number.
● Set category from SQL Statements Cover chapter (last chapter).
● Short description.
● For 10 queries there should be variation in RA.
● Query itself – if there are multiple possibilities of how to write query, write it multiple times –
write description in comment.

Normal text in this chapter should be in sql comments – so it could be all copied, pasted and run in
sql query windows. For commenting one row use -- at start of row. For commenting paragraph use /*
text */

Query list:
/*Query 1 – SQL Category – H3*/
/*Intersection of name from customer and registration table.*/
/*Relational Algebra – {customer[name]} ∩ {registration[name]}*/
SELECT DISTINCT * FROM ( SELECT DISTINCT name FROM customer) AS T0 INTERSECT SELECT
DISTINCT * FROM ( SELECT DISTINCT name FROM registration) AS T2

/*Query 2 – SQL Category – M*/


/*Used view query for Feedback detail */
SELECT * FROM Feedback_Details;

/*Query 3 – SQL Category – l1*/


/*Find and return the maximum value from the package_price column in the packages table.*/
SELECT MAX(package_price) FROM packages;

/*Query 4 – SQL Category – l2*/


/*Customer name under less than 4 id*/
SELECT COUNT(Cu_id), name
FROM Customer
GROUP BY name
HAVING COUNT(Cu_id) < 4;

/*Query 5 – SQL Category – L*/


/*Creating view of Customers feedback details*/
CREATE VIEW Feedback_Details AS SELECT feedback_description, feedback_rating FROM feedback;
SELECT * FROM Feedback_Details;

/*Query 6 – SQL Category – F1*/


/*joining the two tables of customer and registration*/
SELECT customer.name, customer.cu_email, registration.password, registration.c_password FROM
customer JOIN registration ON customer.cu_id = registration.cu_id;

/*Query 7 – SQL Category – O*/


/*Updating the customer name in the payment table*/
UPDATE payment SET cu_name = 'John Deo' WHERE shop_id = 110;
SELECT * FROM payment;

/*Query 8 – SQL Category – A*/


/*Showing the joint of customer and registration*/
SELECT customer.*, registration.name FROM customer
JOIN registration ON customer.cu_id = registration.cu_id WHERE registration.name = 'John Deo';

/*Query 9 – SQL Category – P*/


/*Deleting feedback from shop 10*/
delete FROM feedback WHERE shop_id = 210;

/*Query 10 – SQL Category – L*/


/*To view record of customer feedback*/
/* Relational Algebra - Feedback_Details[*] */
SELECT DISTINCT * FROM Feedback_Details

/*Query 11 – SQL Category – F3*/


/* Cross join between shop and stylist table */
SELECT * FROM shop CROSS JOIN stylist;

/*Query 12 – SQL Category – I2*/


/* group by of shop name and owner having shop name Fantastic Hair Salon*/
SELECT COUNT (shop_id), shop_name, owner_email FROM shop GROUP BY owner_email,
shop_name HAVING shop_name = 'Fantastic Hair Salon' ORDER BY COUNT (shop_id);

/*Query 13 – SQL Category – I1*/


/* Count in shop table*/
SELECT COUNT (shop_id), shop_name, owner_email FROM shop GROUP BY owner_email,
shop_name ORDER BY count (shop_id) DESC;

/*Query 14 – SQL Category – F2*/


/* natural join between shop and stylist*/
/* Relational Algebra - {shop(shop_id=1) [shop_name]} *{stylist[stylist_types]} */
SELECT DISTINCT * FROM ( SELECT DISTINCT shop_name FROM shop WHERE (shop_id=1)) AS T0
NATURAL JOIN ( SELECT DISTINCT stylist_types FROM stylist) AS T2

/*Query 15 – SQL Category – F4*/


/* Right outer join between customer and registration */
/* Relational Algebra - {customer[name,cu_email,cu_mobile]} *>
{registration[name,email,contact]}*/
SELECT DISTINCT name,email,contact FROM ( SELECT DISTINCT name,cu_email,cu_mobile FROM
customer) AS T0 NATURAL JOIN ( SELECT DISTINCT name,email,contact FROM registration) AS T2

/*Query 16 – SQL Category – I1*/


/* Displaying maximum packages using max */
SELECT COUNT (package_id), package_name FROM packages GROUP BY package_name ORDER BY
MAX (package_id) DESC;

/*Query 16 – SQL Category – I1*/


/* Displaying minimum values of shop owner and shop name */
SELECT COUNT (shop_id), shop_name, owner_email FROM shop GROUP BY owner_email,
shop_name ORDER BY MIN (shop_id) DESC;

/*Query 17 – SQL Category – F5*/


/* Full outer join on shop and package name where shop name is fit & fab gym*/
SELECT shop_name FROM shop FULL OUTER JOIN packages ON shop.shop_id = packages.shop_id
WHERE shop_name = 'Fit & Fab Gym';

/*Query 18 – SQL Category – K*/


/* This statement retrieves all shops with the name Fantastic Hair Salon, groups them by shop name,
shop number, and owner email, and then orders them by shop ID, registration ID, and shop name.
The HAVING clause filters the results to only include shops with the description A trendy salon
specializing in hair styling and coloring.*/
SELECT shop_id, registration_id, shop_name, shop_number, owner_email, package_name,
shop_address, shop_description
FROM shop WHERE shop_name = 'Fantastic Hair Salon' GROUP BY shop_id, shop_name,
shop_number, owner_email
HAVING shop_description = 'A trendy salon specializing in hair styling and coloring.' ORDER BY
shop_id, registration_id, shop_name;

/*Query 19 – SQL Category – F4*/


/* This query combines the customer and registration tables in order to retrieve the customers name
and email. The LEFT JOIN ensures that all customer records are included, even if they do not have
corresponding registration data. */
SELECT customer.name, registration.email FROM customer LEFT JOIN registration ON customer.cu_id
= registration.cu_id;

/*Query 20 – SQL Category – G4*/


/* Checking if the shop id is exists in packges table or not inside the shop table*/
SELECT package_name FROM packages WHERE EXISTS (select shop_name FROM shop WHERE
packages.shop_id = shop.shop_id);

/*Query 21 – SQL Category – H1*/


/* union query for stylist and packages table*/
SELECT package_name FROM packages UNION SELECT stylist_types FROM stylist;

/*Query 22 – SQL Category – H2*/


/* Customer name and email except their password and confirm password*/
SELECT name, cu_email FROM customer EXCEPT SELECT password,c_password FROM registration;

/*Query 23 – SQL Category – H3*/


/*Displaying intersection of customer email and login email where customer ID is 5*/
SELECT email FROM registration INTERSECT SELECT user_name_or_email FROM login ;
/*Query 24 – SQL Category – B*/
/* List where cash payment was not accepted*/
/* Relational Algebra - payment[payment_method!='Cash']*/
SELECT DISTINCT payment_method != 'Cash' FROM payment

/*Query 25 – SQL Category – G3*/


/* Retrieve unique feedback records, excluding those associated with booking_id 10, based on the
combination of feedback_rating, feedback_description, and feedback_date from the feedback
table.*/
/* Relational Algebra - {feedback(booking_id <> 10) [feedback_rating, feedback_description,
feedback_date]} */
SELECT DISTINCT * FROM ( SELECT DISTINCT feedback_rating, feedback_description, feedback_date
FROM feedback WHERE (booking_id <> 10)) AS T0

/*Query 26 – SQL Category – G3*/


/* Retrieve unique user emails from the login table, considering the user_name_or_email column,
and present the result set with the alias user_email.*/
/* Relational Algebra - login[user_name_or_email -> user_email] */
SELECT DISTINCT user_name_or_email AS user_email FROM login;

/*Query 27 – SQL Category – G3*/


/* Renaming Name of payment method to google pay */
/* Relational Algebra - payment(payment_id = 5)[payment_method -> Google_Pay] */
SELECT DISTINCT payment_method AS Google_Pay FROM payment WHERE (payment_id = 5);

/*Query 28 – SQL Category – H3*/


/* Retrieve unique names that are common between the customer and registration tables. The query
ensures that only distinct names are considered from each table before identifying their
intersection.*/
/* Relational Algebra - {customer[name]} ∩ {registration[name]}*/
SELECT DISTINCT * FROM ( SELECT DISTINCT name FROM customer) AS T0 INTERSECT SELECT
DISTINCT * FROM ( SELECT DISTINCT name FROM registration) AS T2;

/*Query 29 – SQL Category – F1*/


/* Retrieve payment and feedback information by joining the payment and feedback tables on the
booking_id column. The selected columns include payment method, payment acceptance status,
feedback description, and feedback rating.*/
SELECT payment.payment_method, payment.payment_accept_or_decline,
feedback.feedback_description, feedback.feedback_rating
FROM payment JOIN feedback ON payment.booking_id = feedback.booking_id;

/*Query 30 – SQL Category – I1*/


/* Compute the total sum of the package_price column in the packages table and label the result as
total_package_price. */
SELECT SUM(package_price) AS total_package_price FROM packages;
/*Query 31 – SQL Category – F3*/
/* Retrieve all unique combinations of email, password, c_password, user_name_or_email, and
shop_email by performing a cross join between distinct values selected from the registration and
login tables. The result set includes all possible combinations of these columns from the two
tables.*/
/* Relational Algebra - {registration[email, password, c_password]} ×{login[user_name_or_email,
shop_email]}*/
SELECT DISTINCT * FROM ( SELECT DISTINCT email, password, c_password FROM registration) AS T0
CROSS JOIN ( SELECT DISTINCT user_name_or_email, shop_email FROM login) AS T2

/*Query 32 – SQL Category – M*/


/* Displaying all record of used view query */
SELECT * FROM Feedback_Details;
/*Query 33 – SQL Category – J*/
/* Performing IF Existst on shop table*/
-- Original Query
SELECT DISTINCT shop_id
FROM shop
WHERE package_name = 'Gold Package';
-- Result Obtained
-- Assuming the result is shop_id = 1 (Fantastic Hair Salon)
-- Validity Check Query
SELECT DISTINCT package_name, shop_address
FROM shop s1
WHERE shop_id = 1
AND NOT EXISTS (
SELECT 1
FROM shop s2
WHERE s2.shop_id = s1.shop_id
AND s2.package_name = s1.package_name
AND s2.shop_id <> 1
);

/*Query 34 – SQL Category – J*/


/* Performing LEFT JOIN on shop table*/
-- Original Query
SELECT DISTINCT shop_id
FROM shop
WHERE package_name = 'Gold Package';
-- Result Obtained
-- Assuming the result is shop_id = 1 (Fantastic Hair Salon)
-- Validity Check Query
SELECT DISTINCT s1.package_name, s1.shop_address
FROM shop s1
LEFT JOIN shop s2 ON s1.shop_id = s2.shop_id
AND s1.package_name = s2.package_name
AND s2.shop_id <> 1
WHERE s1.shop_id = 1
AND s2.shop_id IS NULL;
/*Query 35 – SQL Category – J*/
/* Performing GROUP BY and HAVING on shop table*/
-- Original Query
SELECT DISTINCT shop_id
FROM shop
WHERE package_name = 'Gold Package';
-- Result Obtained
-- Assuming the result is shop_id = 1 (Fantastic Hair Salon)
-- Validity Check Query
SELECT package_name, shop_address
FROM shop
WHERE shop_id = 1
GROUP BY package_name, shop_address
HAVING COUNT(DISTINCT shop_id) = 1;

/*Query 36 – SQL Category – G1*/


/* Finding details of user email and shop owner email under id 6 in login table*/
/* Relational Algebra - customer(cu_id < 6) [name, cu_mobile]*/
SELECT DISTINCT name, cu_mobile FROM customer WHERE (cu_id < 6);

/*Query 37 – SQL Category – G1*/


/* Finding details of name and mobile number of customer under id 6*/
/* Relational Algebra - customer(cu_id >= 4) [name, cu_mobile] */
SELECT DISTINCT name, cu_mobile FROM customer WHERE (cu_id >= 4);

/*Query 38 – SQL Category – G1*/


/* Retrieve unique combinations of customer names and emails where the cu_id and email columns
match between the customer and registration tables. The result set includes distinct pairs of names
and customer emails.*/
/* Relational Algebra - {customer[name, cu_email]} <* {registration[cu_id, email]}*/
SELECT DISTINCT name, cu_email FROM ( SELECT DISTINCT name, cu_email FROM customer) AS T0
NATURAL JOIN ( SELECT DISTINCT cu_id, email FROM registration) AS T2

/*Query 39 – SQL Category – C*/


/* This query combines the customer and bookings tables to retrieve customer names and emails
based on bookings they have made. It then excludes customers who have made bookings at other
shops, ensuring that only customers with a single booking at "X" are included. The customer.cu_id is
used to link between the two tables, ensuring that the correct customer data is retrieved. */
SELECT customer.name, customer.cu_email
FROM customer
WHERE customer.cu_id NOT IN (
SELECT bookings.login_id
FROM bookings, shop
WHERE bookings.shop_id = shop.shop_id
);

/* Query 40 – SQL Category – H3 */


/* Intersection of name from customer and registration table. */
/* Relational Algebra - {registration(registration_id=5)[email]} ∩ {login[user_name_or_email]} */
SELECT DISTINCT * FROM ( SELECT DISTINCT email FROM registration WHERE (registration_id=5)) AS
T0 INTERSECT SELECT DISTINCT * FROM ( SELECT DISTINCT user_name_or_email FROM login) AS T2

/* Query 41 – SQL Category – F1 */


/* joining the two tables of customer and registration */
SELECT payment.payment_method, payment.payment_accept_or_decline,
feedback.feedback_description, feedback.feedback_rating FROM payment JOIN feedback ON
payment.shop_id = feedback.shop_id;

/*Query 42 – SQL Category – INSERT_SCRIPT*/


/* The provided INSERT script inserts 2 data into 11 tables within a hypothetical salon management
system. The tables represent various aspects of the salon's operations, including customer
information, bookings, feedback, payment, registration, shops, stylists, and customer feedback.*/
-- Insert data into customer
INSERT INTO customer (name, cu_mobile, cu_email) VALUES
('John Doe', 1234567890, 'john.doe@example.com'),
('Jane Smith', 9876543210, 'jane.smith@example.com');

-- Insert data into bookings


INSERT INTO bookings (login_id, shop_id, booking_date, booking_time) VALUES
(1, 11, '2023-03-21', '11:00 AM'),
(2, 21, '2023-05-20', '05:30 PM');

-- Insert data into feedback


INSERT INTO feedback (feedback_id, booking_id, shop_id, cu_name, feedback_description,
feedback_rating, feedback_date, feedback_time) VALUES
(11, 11, 11, 'John Doe', 'Great service!', '5 stars', '2023-01-02', '11:45 AM'),
(22, 22, 22, 'Jane Smith', 'Excellent experience!', '4 stars', '2023-02-03', '03:15 PM');

-- Insert data into forgot_password


INSERT INTO forgot_password (login_id, registration_id, user_email, shop_email, new_password)
VALUES
(11, 11, 'john.doe@example.com', NULL, 'new_password_123'),
(22, 22, NULL, 'jane.smith@example.com', 'new_password_456');

-- Insert data into login


INSERT INTO login (registration_id, user_name_or_email, user_password, shop_email,
shop_password, forgot_password) VALUES
(11, 'john.doe@example.com', 'password123', NULL, NULL, NULL),
(22, NULL, NULL, 'jane.smith@example.com', 'shop_password', NULL);

-- Insert data into packages


INSERT INTO packages (shop_id, booking_id, bookings_customer_number, package_name,
package_price, hairstyles) VALUES
(11, 11, 123, 'Basic Package', 50, 'Haircut, Shave'),
(2, 2, 456, 'Premium Package', 100, 'Haircut, Styling');

-- Insert data into payment


INSERT INTO payment (payment_id, booking_id, shop_id, cu_name, payment_method,
payment_accept_or_decline) VALUES
(32, 11, 11, 'John Doe', 'Credit Card', true),
(41, 32, 22, 'Jane Smith', 'Cash', false);

-- Insert data into registration


INSERT INTO registration (cu_id, name, email, contact, password, c_password) VALUES
(11, 'John Doe', 'john.doe@example.com', 1234567890, 'password123', 'password123'),
(22, 'Jane Smith', 'jane.smith@example.com', 9876543210, 'password456', 'password456');

-- Insert data into shop


INSERT INTO shop (registration_id, shop_name, shop_number, owner_email, package_name,
shop_address, shop_description) VALUES
(11, 'Salon A', 1112223333, 'owner11@example.com', 'Basic Package', '123 Main St', 'Modern salon
with experienced stylists'),
(22, 'Barber Shop B', 4445556666, 'owner22@example.com', 'Premium Package', '456 Oak St',
'Traditional barber shop with a twist');

-- Insert data into stylist


INSERT INTO stylist (booking_id, shop_id, stylist_name, stylist_types, stylist_price) VALUES
(11, 11, 'Stylist 1A', 'Haircut, Shave', 30),
(22, 22, 'Stylist 2B', 'Haircut, Styling', 40);

-- Insert data into customer_feedback


INSERT INTO customer_feedback (customer_name, feedback_cu_name) VALUES
('John Doe', 'John Doe'),
('Jane Smith', 'Jane Smith');

/*Query 41 – SQL Category – DDL_SCRIPT*/


/* These SQL will create all tables in the schema called public*/
CREATE TABLE IF NOT EXISTS public.login
(
login_id serial NOT NULL,
registration_id serial,
user_name_or_email character varying(256) COLLATE pg_catalog."default",
user_password character varying(256) COLLATE pg_catalog."default",
forgot_password character varying(256) COLLATE pg_catalog."default",
shop_email character varying(256) COLLATE pg_catalog."default",
shop_password character varying(256) COLLATE pg_catalog."default",
CONSTRAINT pk_login PRIMARY KEY (login_id),
CONSTRAINT u_fk_login_registration UNIQUE (registration_id),
CONSTRAINT uc_login_shop_email UNIQUE (shop_email)
);

CREATE TABLE IF NOT EXISTS public.registration


(
registration_id serial NOT NULL,
cu_id serial,
name text COLLATE pg_catalog."default",
email character varying(256) COLLATE pg_catalog."default",
contact numeric(10),
password character varying(256) COLLATE pg_catalog."default",
c_password character varying(256) COLLATE pg_catalog."default",
CONSTRAINT pk_registration PRIMARY KEY (registration_id),
CONSTRAINT u_fk_email UNIQUE (email)
);

CREATE TABLE IF NOT EXISTS public.customer


(
cu_id integer NOT NULL,
cu_name text COLLATE pg_catalog."default",
cu_email character varying(256) COLLATE pg_catalog."default",
cu_mobile numeric(10),
CONSTRAINT pk_customer PRIMARY KEY (cu_id),
CONSTRAINT uc_customer_customer_email UNIQUE (cu_email)
);

CREATE TABLE IF NOT EXISTS public.bookings


(
booking_id serial NOT NULL,
login_id serial,
shop_id serial,
booking_date character varying(256) COLLATE pg_catalog."default",
booking_time character varying(256) COLLATE pg_catalog."default",
CONSTRAINT pk_bookings PRIMARY KEY (booking_id)
);

CREATE TABLE IF NOT EXISTS public.shop


(
shop_id serial NOT NULL,
registration_id serial,
shop_name text COLLATE pg_catalog."default",
shop_number numeric(10),
owner_email character varying(256) COLLATE pg_catalog."default",
package_name character varying(256) COLLATE pg_catalog."default",
shop_address character varying(256) COLLATE pg_catalog."default",
shop_description character varying(256) COLLATE pg_catalog."default",
CONSTRAINT pk_shop PRIMARY KEY (shop_id),
CONSTRAINT uc_shop_owner_email UNIQUE (owner_email),
CONSTRAINT uc_shop_packages UNIQUE (package_name)
);

CREATE TABLE IF NOT EXISTS public.feedback


(
feedback_id integer NOT NULL,
booking_id integer,
bookings_customer_id integer,
shop_id integer,
shop_shop_id integer,
cu_name character varying(256) COLLATE pg_catalog."default",
feedback_description character varying(256) COLLATE pg_catalog."default",
feedback_rating character varying(256) COLLATE pg_catalog."default",
feedback_date date,
feedback_time character varying(256) COLLATE pg_catalog."default",
CONSTRAINT pk_feedback PRIMARY KEY (feedback_id),
CONSTRAINT uc_feedback_customer_id UNIQUE (bookings_customer_id, shop_shop_id, cu_name,
shop_id)
);

CREATE TABLE IF NOT EXISTS public.stylist


(
stylist_id serial,
booking_id integer,
shop_id serial,
stylist_name text,
stylist_types character varying(256),
stylist_price numeric(5)
);

CREATE TABLE IF NOT EXISTS public.packages


(
package_id serial NOT NULL,
shop_id serial,
booking_id serial,
bookings_customer_number integer,
package_name character varying(256) COLLATE pg_catalog."default",
package_price numeric(7),
hairstyles character varying(256) COLLATE pg_catalog."default",
CONSTRAINT pk_packages PRIMARY KEY (package_id),
CONSTRAINT u_fk_packages_bookings UNIQUE (booking_id, bookings_customer_number,
shop_id)
);

CREATE TABLE IF NOT EXISTS public.payment


(
payemnt_id serial NOT NULL,
booking_id character varying(256) COLLATE pg_catalog."default",
bookings_booking_id integer,
shop_id serial,
cu_name character varying(256),
payment_method character varying(256) COLLATE pg_catalog."default",
payment_accept_or_decline boolean,
CONSTRAINT pk_payment PRIMARY KEY (payemnt_id),
CONSTRAINT u_fk_payment_bookings UNIQUE (bookings_booking_id, cu_name, shop_id),
CONSTRAINT uc_payment_booking_id UNIQUE (booking_id)
);

CREATE TABLE IF NOT EXISTS public.forgot_password


(
forgotpassword_id serial NOT NULL,
login_id serial NOT NULL,
registration_id serial,
user_email character varying(256) COLLATE pg_catalog."default",
shop_email character varying(256) COLLATE pg_catalog."default",
new_password character varying(256) COLLATE pg_catalog."default",
CONSTRAINT pk_forgot_password PRIMARY KEY (forgotpassword_id, login_id),
CONSTRAINT u_fk_forgot_password_login UNIQUE (login_id, registration_id),
CONSTRAINT uc_forgot_password_shop_email UNIQUE (shop_email),
CONSTRAINT uc_forgot_password_user_email UNIQUE (user_email)
);
Sample data
Normal text in this chapter should be in sql comments – so it could be all copied, pasted and run in
sql query windows. For commenting one row use -- at start of row. For commenting paragraph use /*
text */

Sample data list:


/* This is the sql syntax for inserting sample data in each table */

-- Insert sample data into public.customer

INSERT INTO public.customer (name, cu_mobile, cu_email) VALUES

('John Doe', 1234567890, 'john.doe@example.com'),

('Jane Smith', 9876543210, 'jane.smith@example.com');

-- Insert sample data into public.bookings

INSERT INTO public.bookings (login_id, shop_id, booking_date, booking_time) VALUES

(1, 1, '2023-01-01', '10:00 AM'),

(2, 2, '2023-02-01', '02:30 PM');

-- Insert sample data into public.feedback

INSERT INTO public.feedback (booking_id, shop_id, cu_name, feedback_description,


feedback_rating, feedback_date, feedback_time) VALUES

(1, 1, 'John Doe', 'Great service!', '5', '2023-01-02', '11:45 AM'),

(2, 2, 'Jane Smith', 'Excellent experience!', '4', '2023-02-02', '03:00 PM');

-- Insert sample data into public.forgot_password

INSERT INTO public.forgot_password (login_id, registration_id, user_email, shop_email,


new_password) VALUES

(1, 1, 'john.doe@example.com', NULL, 'newpassword123'),

(2, 2, 'jane.smith@example.com', NULL, 'securepass');

-- Insert sample data into public.login

INSERT INTO public.login (registration_id, user_email, user_password, shop_email, shop_password,


forgot_password) VALUES
(1, 'john.doe@example.com', 'userpass123', NULL, NULL, 'forgot123'),

(2, 'jane.smith@example.com', 'securepass456', NULL, NULL, 'forgot456');

-- Insert sample data into public.packages

INSERT INTO public.packages (shop_id, booking_id, bookings_customer_number, package_name,


package_price, hairstyles) VALUES

(1, 1, 1, 'Standard Package', 50, 'Haircut, Shave'),

(2, 2, 2, 'Premium Package', 80, 'Haircut, Color, Style');

-- Insert sample data into public.payment

INSERT INTO public.payment (booking_id, bookings_booking_id, shop_id, cu_name,


payment_method, payment_accept_or_decline) VALUES

(1, 1, 1, 'John Doe', 'Credit Card', true),

(2, 2, 2, 'Jane Smith', 'Cash', true);

-- Insert sample data into public.registration

INSERT INTO public.registration (cu_id, name, email, contact, password, c_password) VALUES

(1, 'John Doe', 'john.doe@example.com', 1234567890, 'userpass123', 'userpass123'),

(2, 'Jane Smith', 'jane.smith@example.com', 9876543210, 'securepass456', 'securepass456');

-- Insert sample data into public.shop

INSERT INTO public.shop (registration_id, shop_name, shop_number, owner_email, package_name,


shop_address, shop_description) VALUES

(1, 'Barber Shop 1', 1111111111, 'john.doe@example.com', 'Standard Package', '123 Main St',
'Quality haircuts for men'),

(2, 'Salon 2', 2222222222, 'jane.smith@example.com', 'Premium Package', '456 Oak St', 'Full-service
salon for men and women');

-- Insert sample data into public.stylist

INSERT INTO public.stylist (booking_id, shop_id, stylist_name, stylist_types, stylist_price) VALUES

(1, 1, 'Stylist A', 'Haircut, Shave', 30),

(2, 2, 'Stylist B', 'Haircut, Color, Style', 50);


SQL Statements Cover
Category Category statement description

A Simple (positive) query with at least two joined tables (list of patients - name, address
who were examined by doctor Braun)

B Simple (negative) query (list of patients - name, address who were not visiting doctor
Braun) (select all doctors who had patients,...)

C Choose all records, which have relation for "X" only …(list of patients - name, address
who were examined by doctor Braun ONLY - the patients didn't have visit at another
doctor).

D1 Select all records which are at the relation with all.General quantified query (list of
doctors - name, address who were visited by EACH patient, who visited doctor Braun)

D2 The result validity check from category D1. For example if query {list of teachers, who
had lecture during ALL semesters begin at winter 2001/2002 till summer semester
2008/2008 included} shows the teacher "123 Josef Pavlicek", so the validity check will
be query {{list of all semester at the season, where was teaching Pavlicek }\ (minus){list
of all semester at the season}} and the result must be empty.

F1 join - JOIN ON

F2 NATURAL JOIN | JOIN USING

F3 CROSS JOIN

F4 LEFT | RIGHT OUTER JOIN

F5 FULL (OUTER) JOIN

G1 Subquery inside WHERE

G2 Subquery inside FROM

G3 Subquery inside SELECT

G4 Correlated subquery (EXISTS | NOT EXISTS)

H1 Set union query - UNION

H2 Set substraction query - EXCEPT or MINUS (v Oracle)

H3 Set intersection - INTERSECT

I1 Aggregation functions (count | sum | min | max| avg)

I2 Aggregations with GROUP BY (HAVING) clause

J The same query using three different formulations in SQL

K All select clauses - SELECT FROM WHERE GROUP BY HAVING ORDER BY

L Make VIEW

M View used query


N Insert statement for inserting list of records - INSERT without clause VALUES use, for
example ( add customer ID 6 all green boats reservation for all needed time intervals)

O UPDATE statement with subquery in WHERE/SET

P DELETE statement with subquery in WHERE clause

You might also like