Databases | Tasks for Practical Class 8 (915-23 KII)
Creating Queries Using Standard Functions in PostgreSQL.
Variant 1: Library Management System
Scenario: You are managing a database for a local library. You need to perform various queries related to members, books, and loans.
Database Schema:
-- Drop tables if they exist (optional)
-- DROP TABLE IF EXISTS loans;
-- DROP TABLE IF EXISTS books;
-- DROP TABLE IF EXISTS members;
-- 1. Create the 'members' table
CREATE TABLE members (
member_id SERIAL PRIMARY KEY,
first_name VARCHAR(50) NOT NULL,
last_name VARCHAR(50) NOT NULL,
email VARCHAR(100) UNIQUE, -- For LOWER() and UNIQUE practice
join_date DATE NOT NULL,
membership_level VARCHAR(10) DEFAULT 'Bronze', -- For CASE or NULLIF
postal_code VARCHAR(10) -- Might have extra spaces, for TRIM()
);
-- 2. Create the 'books' table
CREATE TABLE books (
book_id SERIAL PRIMARY KEY,
title VARCHAR(255) NOT NULL,
author VARCHAR(100),
isbn VARCHAR(20) UNIQUE, -- May have hyphens/spaces, for REPLACE()
publication_year INTEGER, -- For EXTRACT() or CAST()
list_price NUMERIC(7, 2) -- For ROUND(), CEIL(), FLOOR(), ABS()
);
-- 3. Create the 'loans' table
CREATE TABLE loans (
loan_id SERIAL PRIMARY KEY,
book_id INTEGER REFERENCES books(book_id),
member_id INTEGER REFERENCES members(member_id),
loan_date DATE NOT NULL DEFAULT CURRENT_DATE,
due_date DATE NOT NULL,
return_date DATE -- NULL if not returned, for COALESCE(), AGE()
);
-- Sample Data Insertion --
INSERT INTO members (first_name, last_name, email, join_date, membership_level, postal_code) VALUES
('Arthur', 'Dent', 'a.dent@galaxy.net', '2021-03-15', 'Silver', ' SW1A0AA'),
('Ford', 'Prefect', 'ford.p@betelgeuse.com', '2021-03-15', 'Gold', 'BG5-XQ1 '),
('Zaphod', 'Beeblebrox', 'z.beeblebrox@president.gov', '2022-11-01', NULL, 'HHGTTG'), -- NULL level
('Trillian', 'Astra', 'trillian@heartofgold.spc', '2020-08-25', 'Gold', ' E1 6AN'),
('Marvin', 'Android', 'paranoid.android@sirius.cyb', '2023-01-10', 'Bronze', ' ROBOT01');
INSERT INTO books (title, author, isbn, publication_year, list_price) VALUES
('The Hitchhiker''s Guide', 'Douglas Adams', '0-345-39180-2', 1979, 15.99),
('Dirk Gently''s Holistic Detective Agency', 'Douglas Adams', ' 0-671-69464-4', 1987, 18.50), -- Leading space ISBN
('Good Omens', 'Terry Pratchett & Neil Gaiman', '0-575-04800-X ', 1990, 22.00), -- Trailing space ISBN
('Stardust', 'Neil Gaiman', '0-380-97728-1', 1999, 14.75),
('Hyperion', 'Dan Simmons', '978-0553283686', 1989, 19.95);
INSERT INTO loans (book_id, member_id, loan_date, due_date, return_date) VALUES
(1, 1, '2023-10-01', '2023-10-15', '2023-10-14'),
(2, 2, '2023-10-05', '2023-10-26', NULL), -- Overdue
(3, 1, '2023-10-10', '2023-10-31', NULL), -- Not yet due (assume today is Oct 26th)
(4, 3, '2023-09-15', '2023-10-06', '2023-10-10'), -- Returned late
(5, 4, '2023-10-20', '2023-11-10', NULL),
(1, 5, '2023-08-01', '2023-08-22', NULL); -- Very overdue
Tasks for Variant 1:
- Member Full Names: Select the
member_idand generate a full name string for each member by concatenating theirfirst_nameandlast_name, separated by a space. Alias this column asfull_name. - Cleaned ISBNs: Display the
titleandisbnfor all books. Clean theisbnby removing both leading/trailing spaces and any hyphens (‘-‘). Alias the cleaned column ascleaned_isbn. (Hint: You might needTRIMandREPLACE). - Membership Duration: Calculate how long each member has been part of the library as of
CURRENT_DATE. Display the member’sfirst_name,join_date, and the calculated duration usingAGE(). Alias the duration column asmembership_duration. - Loan Status: For all loans, display the
loan_id,due_date, and a calculatedstatus. The status should be ‘Overdue’ if thereturn_dateis NULL AND thedue_dateis beforeCURRENT_DATE. The status should be ‘Returned’ ifreturn_dateis NOT NULL. Otherwise, the status should be ‘On Loan’. (Hint: UseCASEand check forNULL). - Book Pricing Categories: Show the
title,list_price, and aprice_categoryfor each book. Categorize as ‘Budget’ if price < $15.00, ‘Standard’ if price is between $15.00 and $19.99 (inclusive), and ‘Premium’ if $20.00 or more. - Member Email Lowercase: Display the
first_name,last_name, andemailaddress for all members, ensuring the email address is entirely in lowercase. Alias the lowercase email column aslower_email. - Book Title Abbreviation: Show the
book_idand the first 15 characters of each book’stitle. If the title is longer than 15 characters, append ‘…’. Alias this asshort_title. (Hint: UseSUBSTRINGand potentiallyLENGTHandCONCAT/||). - Loan Period: Calculate the number of days between the
loan_dateanddue_datefor each loan. Displayloan_idand the calculated number of days asloan_period_days. (Hint: Date subtraction results in an integer number of days). - Price Rounded Up: Display the
titleandlist_pricefor each book, along with the price rounded UP to the nearest whole dollar amount. Alias this asprice_ceil. - Membership Level Display: Show the
member_idandfirst_name. Also display themembership_level. If themembership_levelis NULL, display ‘Standard’ instead. Alias this column aseffective_level. (Hint: UseCOALESCE). - Extract Join Quarter: Display the
first_nameandjoin_datefor each member. Also, extract the calendar quarter (1, 2, 3, or 4) from theirjoin_date. Alias this asjoin_quarter. (Hint: UseEXTRACT(QUARTER FROM ...)). - Postal Code Cleanup: Display the
member_idand thepostal_codefor each member, removing any leading or trailing spaces. Alias the cleaned column astrimmed_postal_code. - Absolute Price Difference: Calculate the absolute difference between each book’s
list_priceand a target price of $18.00. Display thetitle,list_price, and the calculatedabsolute_difference. - Numeric ISBN Check (Conceptual): Identify books where the
cleaned_isbn(from Task 2 logic) contains non-numeric characters (excluding potential ‘X’ at the end, common in ISBN-10). This is more complex; for this assignment, simply check ifREPLACE(TRIM(isbn), '-', '')results in NULL when attempting to cast to a NUMERIC type (useNULLIFcombined with a check or a more advanced technique if known, otherwise describe the logic). For a simpler version: Return NULL usingNULLIFif thepublication_yearis exactly1990. Alias this asnull_if_1990_pub. - Member ID Padding: Display the
member_idfor all members, formatted as a 5-digit string with leading zeros (e.g., 1 becomes ‘00001’). Alias this asformatted_member_id. (Hint: UseLPADafter casting).
Variant 2: University Course Enrollment
Scenario: You are managing a database for university enrollments, tracking students, courses, and their grades.
Database Schema:
-- Drop tables if they exist (optional)
-- DROP TABLE IF EXISTS enrollments;
-- DROP TABLE IF EXISTS courses;
-- DROP TABLE IF EXISTS students;
-- 1. Create the 'students' table
CREATE TABLE students (
student_id SERIAL PRIMARY KEY,
first_name VARCHAR(50) NOT NULL,
middle_name VARCHAR(50), -- Allows NULLs, for COALESCE
last_name VARCHAR(50) NOT NULL,
email VARCHAR(100) UNIQUE NOT NULL, -- For LOWER(), UNIQUE
date_of_birth DATE, -- For AGE(), EXTRACT()
major VARCHAR(50) -- For CASE, NULLIF
);
-- 2. Create the 'courses' table
CREATE TABLE courses (
course_id SERIAL PRIMARY KEY,
course_code VARCHAR(15) UNIQUE NOT NULL, -- e.g., ' CS 101 ', for TRIM()
course_name VARCHAR(100) NOT NULL, -- For UPPER(), SUBSTRING()
credits NUMERIC(3, 1), -- e.g., 3.0, 1.5. For ROUND(), ABS()
department VARCHAR(50) -- For general queries
);
-- 3. Create the 'enrollments' table
CREATE TABLE enrollments (
enrollment_id SERIAL PRIMARY KEY,
student_id INTEGER REFERENCES students(student_id),
course_id INTEGER REFERENCES courses(course_id),
enrollment_date DATE DEFAULT CURRENT_DATE, -- For EXTRACT(), INTERVAL
grade NUMERIC(4, 1) -- e.g. 85.5, 92.0. Allows NULL if not graded. For CEIL(), FLOOR(), CASE
);
-- Sample Data Insertion --
INSERT INTO students (first_name, middle_name, last_name, email, date_of_birth, major) VALUES
('Alice', 'Marie', 'Wonder', 'alice.wonder@uni.edu', '2003-04-10', 'Literature'),
('Bob', NULL, 'Builder', 'bob.the.builder@uni.edu', '2002-08-20', 'Engineering'),
('Charlie', 'Chaplin', 'Jr', 'charlie.jr@uni.edu', '2004-01-05', NULL), -- NULL Major
('Dorothy', 'Gale', 'Oz', 'dorothy.oz@uni.edu', '2003-11-11', 'Meteorology'),
('Eve', 'Ada', 'Lovelace', 'eve.lovelace@uni.edu', '2002-12-15', 'Computer Science');
INSERT INTO courses (course_code, course_name, credits, department) VALUES
(' CS 101 ', 'Introduction to Programming', 3.0, 'Computer Science'), -- Spaces in code
('LIT 205', 'Modernist Poetry', 3.0, 'Literature'),
(' ENG 310', 'Structural Analysis', 4.0, 'Engineering'), -- Leading space
('MATH 150 ', 'Calculus I', 4.5, 'Mathematics'), -- Trailing space
('CS 336', 'Database Systems', 3.0, 'Computer Science');
INSERT INTO enrollments (student_id, course_id, enrollment_date, grade) VALUES
(1, 2, '2023-09-05', 88.5),
(2, 3, '2023-09-05', 92.0),
(1, 4, '2023-09-06', 75.0),
(3, 1, '2023-09-07', NULL), -- Not graded yet
(4, 4, '2023-09-06', 65.5),
(5, 1, '2023-09-07', 95.0),
(5, 5, '2023-09-08', NULL); -- Not graded yet
Tasks for Variant 2:
- Student Initials and Full Name: Display the
student_id. Create afull_name(First Last). Create aninitialsstring using the first letter of thefirst_nameand the first letter of thelast_namein uppercase (e.g., ‘AW’). If amiddle_nameexists, display it usingCOALESCE(show ‘N/A’ if NULL), otherwise skip the middle name display for this task. - Cleaned Course Codes: Show the
course_nameand thecourse_codeafter removing any leading or trailing whitespace. Alias the cleaned code asclean_code. - Student Age Calculation: Calculate the current age of each student based on their
date_of_birthas ofCURRENT_DATE. Displayfirst_name,last_name,date_of_birth, and the calculatedage. - Enrollment Grade Status: Display the
enrollment_id,student_id,course_id, and a calculatedgrade_status. The status should be ‘Passed’ ifgrade>= 60, ‘Failed’ ifgrade< 60, and ‘Pending’ ifgradeis NULL. - Course Credit Categories: Display the
course_name,credits, and acredit_category. Categorize as ‘Low’ if credits < 3.0, ‘Standard’ if credits are 3.0 or 3.5, and ‘High’ if credits > 3.5. - Standardized Student Emails: Show the
student_id,first_name, andemail, ensuring theemailis entirely in lowercase. Alias this asstandard_email. - Course Name Abbreviation: Display the
course_idand the first 20 characters of thecourse_name. Alias this asshort_course_name. - Semester of Enrollment: Display the
enrollment_idandenrollment_date. Determine the semester of enrollment based on the month: Month 1-5 = ‘Spring’, Month 6-8 = ‘Summer’, Month 9-12 = ‘Fall’. Alias this asenrollment_semester. (Hint: UseEXTRACTandCASE). - Grade Rounded Down: Display the
enrollment_idandgrade. Also show thegraderounded DOWN to the nearest whole number. Alias this asgrade_floor. Handle cases where grade might be NULL (it should likely remain NULL). - Major Display: Display the
student_idandfirst_name. UseCOALESCEto show the student’smajor; if themajoris NULL, display ‘Undeclared’. Alias this asdeclared_major. - Years Since Birth Year: Extract the birth year for each student. Calculate the number of full years that have passed between their birth year and the current year. Display
first_name,date_of_birth, andyears_passed. (Hint:EXTRACT(YEAR FROM CURRENT_DATE) - EXTRACT(YEAR FROM date_of_birth)). - Absolute Grade Difference from Average: Calculate the absolute difference between each student’s
gradein ‘Calculus I’ (Course ID 4) and the average grade for that course (assume average is 70.0 for this task). Displaystudent_id,grade, andabs_diff_from_avg. Only include enrollments for Course ID 4 with non-null grades. - Find Null Majors: Use
NULLIFto return NULL if a student’s major is ‘Literature’. Otherwise, return the major. Displaystudent_id,first_name,major, and the result asnull_if_literature. - Check Student ID Parity: Determine if a
student_idis odd or even. Display thestudent_idand ‘Even’ or ‘Odd’ asid_parity. (Hint: UseMODor%). - Course Code Padding: Display the
course_idandclean_code(from Task 2 logic). Create apadded_codeby padding theclean_codeon the right with spaces up to a total length of 10 characters. (Hint: UseRPAD).
Variant 3: Project & Task Management
Scenario: You are managing a database for tracking projects, tasks assigned to employees, and their progress.
Database Schema:
-- Drop tables if they exist (optional)
-- DROP TABLE IF EXISTS tasks;
-- DROP TABLE IF EXISTS projects;
-- DROP TABLE IF EXISTS employees;
-- 1. Create the 'employees' table
CREATE TABLE employees (
emp_id SERIAL PRIMARY KEY,
first_name VARCHAR(50) NOT NULL,
last_name VARCHAR(50) NOT NULL,
emp_code VARCHAR(10) UNIQUE, -- e.g., 'EMP001', for SUBSTRING, CAST
hire_date DATE NOT NULL, -- For AGE(), EXTRACT()
hourly_rate NUMERIC(6, 2), -- For ROUND(), numeric ops
department VARCHAR(50) -- For general queries, NULLIF
);
-- 2. Create the 'projects' table
CREATE TABLE projects (
project_id SERIAL PRIMARY KEY,
project_name VARCHAR(100) NOT NULL UNIQUE, -- For UPPER(), LENGTH()
client_name VARCHAR(100),
start_date DATE NOT NULL,
deadline_date DATE, -- Allows NULL, for COALESCE, CASE
budget NUMERIC(12, 2) -- For ABS(), CEIL()
);
-- 3. Create the 'tasks' table
CREATE TABLE tasks (
task_id SERIAL PRIMARY KEY,
project_id INTEGER REFERENCES projects(project_id),
assigned_to_emp_id INTEGER REFERENCES employees(emp_id), -- Allows NULL
task_name VARCHAR(255) NOT NULL,
estimated_hours NUMERIC(5, 1), -- e.g., 8.0, 2.5. For ROUND()
creation_date TIMESTAMP DEFAULT NOW(), -- For date/time functions
completion_date DATE -- NULL if not completed. For CASE, AGE()
);
-- Sample Data Insertion --
INSERT INTO employees (first_name, last_name, emp_code, hire_date, hourly_rate, department) VALUES
('Peter', 'Gibbons', 'EMP001', '2019-02-15', 35.00, 'Software'),
('Michael', 'Bolton', 'EMP002', '2018-07-01', 40.50, NULL), -- NULL Dept
('Samir', 'Nagheenanajar', 'EMP003', '2019-02-15', 38.75, 'Software'),
('Joanna', 'Planter', 'EMP004', '2020-11-20', 45.00, 'Management'),
('Bill', 'Lumbergh', 'EMP005', '2015-03-10', 75.00, 'Management');
INSERT INTO projects (project_name, client_name, start_date, deadline_date, budget) VALUES
('TPS Reports Automation', 'Initech', '2023-01-10', '2023-06-30', 50000.00),
('Website Redesign', 'Globex Corp', '2023-03-01', '2023-09-15', 75000.50),
('New Feature X', 'Initech', '2023-05-15', NULL, 30000.00), -- NULL Deadline
('Server Migration', 'Stark Industries', '2023-08-01', '2023-12-20', 120000.00);
INSERT INTO tasks (project_id, assigned_to_emp_id, task_name, estimated_hours, creation_date, completion_date) VALUES
(1, 1, 'Analyze current TPS report process', 8.0, '2023-01-12 10:00:00', '2023-01-20'),
(1, 3, 'Develop script for data extraction', 24.5, '2023-02-01 11:30:00', '2023-03-15'),
(2, 4, 'Create wireframes for new website', 16.0, '2023-03-05 09:00:00', NULL), -- Not completed
(2, NULL, 'Content population', 40.0, '2023-06-01 14:00:00', NULL), -- Unassigned
(3, 1, 'Define requirements for Feature X', 4.0, '2023-05-16 15:00:00', '2023-05-25'),
(4, 5, 'Plan migration strategy', 12.0, '2023-08-02 16:20:00', NULL),
(1, 5, 'Oversee TPS report testing', 6.5, '2023-04-01 08:00:00', '2023-06-10');
Tasks for Variant 3:
- Employee Full Name and Code: Display the
emp_id. Concatenatefirst_nameandlast_nameintofull_name. Also display theemp_code. - Project Name Uppercase: Show the
project_idand theproject_nameentirely in uppercase, aliased asupper_project_name. - Employee Tenure: Calculate the duration each employee has been working at the company as of
CURRENT_DATE. Displayemp_code,hire_date, and the calculatedtenureusingAGE(). - Task Status Determination: Display the
task_id,task_name,deadline_date(from the associated project - requires a JOIN, assume you can look up the project deadline manually for now or just use taskcompletion_date). Provide astatus: ‘Completed’ ifcompletion_dateis NOT NULL, ‘Overdue’ ifcompletion_dateIS NULL AND the project’sdeadline_dateis beforeCURRENT_DATE(if deadline exists), ‘In Progress’ otherwise. (Simplified for assignment: Use onlycompletion_date. ‘Completed’ if NOT NULL, ‘Pending’ if NULL). - Project Budget Categories: Display
project_name,budget. Categorize projects based onbudget: ‘Small’ if budget < 40000, ‘Medium’ if budget is between 40000 and 80000 (inclusive), ‘Large’ if budget > 80000. Alias asbudget_category. - Estimated Hours Rounded: Show the
task_id,task_name, andestimated_hours. Also display theestimated_hoursrounded to the nearest whole number. Alias this asrounded_hours. - Employee Code Numeric Part: Extract the numeric part of the
emp_code(assuming format ‘EMP’ followed by numbers). Displayemp_id,emp_code, and the extracted number asemp_number. (Hint: UseSUBSTRINGand possiblyCAST). - Days Until Project Deadline: For projects that have a
deadline_date, calculate the number of days remaining fromCURRENT_DATEuntil the deadline. Displayproject_name,deadline_date, anddays_remaining. Handle cases where the deadline might be in the past (result will be negative). - Budget Rounded Up: Display the
project_nameandbudget. Also show thebudgetrounded UP to the nearest 1000 dollars. Alias this asbudget_ceil_k. (Hint: UseCEILcarefully, maybe divide, ceil, then multiply, or useROUNDwith negative precision appropriately if the goal is nearest 1000, useCEILif strictly UP). Let’s stick toCEILfor the tutorial concept: displayCEIL(budget)asbudget_ceil_dollar. - Assigned Employee Display: Display
task_idandtask_name. UseCOALESCEto show theassigned_to_emp_id. If it’s NULL, display 0 instead. Alias this asassigned_emp. - Project Start Month and Year: Extract the month and year from the
start_datefor each project. Displayproject_name,start_date,start_month, andstart_year. - Absolute Budget Deviation: Calculate the absolute difference between each project’s
budgetand a standard budget of $60,000. Displayproject_name,budget, andabs_budget_deviation. - Task Creation Hour: Extract the hour (0-23) from the
creation_datetimestamp for each task. Displaytask_id,creation_date, andcreation_hour. - Find Non-Software Employees: Use
NULLIFto return NULL if an employee’s department is ‘Software’. Otherwise, return the department. Displayemp_id,first_name,department, and the result asnull_if_software. -
Format Hourly Rate: Display the emp_id, first_name, and hourly_rate. Create a new string column named formatted_rate that shows the hourly_rate prefixed with a dollar sign (‘$’). (Hint: Use the concatenation operator and cast the hourly_rate to VARCHAR).
Variant 4: E-commerce Order System
Scenario: You are managing the database for an online retail store. You need to query customer information, product details, orders, and the items within those orders.
Database Schema:
-- Drop tables if they exist (optional)
-- DROP TABLE IF EXISTS order_items;
-- DROP TABLE IF EXISTS orders;
-- DROP TABLE IF EXISTS products;
-- DROP TABLE IF EXISTS customers;
-- 1. Create the 'customers' table
CREATE TABLE customers (
customer_id SERIAL PRIMARY KEY,
first_name VARCHAR(50) NOT NULL,
last_name VARCHAR(50) NOT NULL,
email VARCHAR(100) UNIQUE NOT NULL, -- For LOWER(), UNIQUE
registration_date DATE NOT NULL DEFAULT CURRENT_DATE, -- For AGE(), EXTRACT()
address_line1 VARCHAR(255),
city VARCHAR(100),
postal_code VARCHAR(20) -- Might have spaces, for TRIM()
);
-- 2. Create the 'products' table (different structure from tutorial)
CREATE TABLE products (
product_sku VARCHAR(50) PRIMARY KEY, -- e.g., 'ELEC-LAP-1001', 'BOOK-FIC-205A'
product_name VARCHAR(150) NOT NULL, -- For SUBSTRING(), UPPER()
description TEXT, -- For LENGTH() (on excerpt)
unit_price NUMERIC(10, 2) NOT NULL CHECK (unit_price > 0), -- For ROUND(), CEIL(), FLOOR(), ABS()
category VARCHAR(50), -- For CASE, NULLIF
stock_added_date DATE -- For INTERVAL calculation
);
-- 3. Create the 'orders' table
CREATE TABLE orders (
order_id SERIAL PRIMARY KEY,
customer_id INTEGER NOT NULL REFERENCES customers(customer_id),
order_date TIMESTAMP NOT NULL DEFAULT NOW(), -- For EXTRACT(), AGE()
shipping_address VARCHAR(500), -- Could be different from customer address, maybe NULL
order_status VARCHAR(20) DEFAULT 'Pending', -- e.g., 'Pending', 'Shipped', 'Delivered', 'Cancelled'
-- total_amount NUMERIC(12, 2) -- Usually calculated, but could be stored
discount_code VARCHAR(15) NULL -- For COALESCE
);
-- 4. Create the 'order_items' table (linking orders and products)
CREATE TABLE order_items (
item_id SERIAL PRIMARY KEY,
order_id INTEGER NOT NULL REFERENCES orders(order_id),
product_sku VARCHAR(50) NOT NULL REFERENCES products(product_sku),
quantity INTEGER NOT NULL CHECK (quantity > 0),
price_per_unit NUMERIC(10, 2) NOT NULL -- Price at the time of order
);
-- Sample Data Insertion --
INSERT INTO customers (first_name, last_name, email, registration_date, postal_code) VALUES
('Jane', 'Doe', 'jane.d@email.com', '2022-01-15', ' 12345 '),
('John', 'Smith', 'J.Smith@email.com', '2021-11-30', '98765'),
('Peter', 'Jones', 'peterjones@email.com', '2023-05-20', ' SW1A 0AA'),
('Mary', 'Brown', 'mary.b@email.com', '2022-01-15', NULL); -- NULL postal code
INSERT INTO products (product_sku, product_name, description, unit_price, category, stock_added_date) VALUES
('ELEC-LAP-1001', 'UltraBook X1', 'A thin and light laptop.', 1299.99, 'Electronics', '2023-01-10'),
('BOOK-FIC-205A', 'The Forgotten Realm', 'A fantasy novel.', 19.95, 'Books', '2023-02-15'),
('HOME-KIT-050', 'Smart Coffee Maker', 'Brews coffee remotely.', 89.50, 'Home Goods', '2023-03-01'),
('ELEC-CAM-300', 'Action Camera Pro', NULL, 249.00, 'Electronics', '2023-01-10'), -- NULL description
('BOOK-NF-110B', 'History of Computing', 'Covers major milestones.', 35.00, 'Books', '2022-12-01');
INSERT INTO orders (customer_id, order_date, order_status, discount_code) VALUES
(1, '2023-10-01 10:30:00', 'Shipped', 'FALL10'),
(2, '2023-10-15 14:00:00', 'Pending', NULL),
(1, '2023-10-20 09:00:00', 'Pending', NULL),
(3, '2023-08-10 11:00:00', 'Delivered', NULL),
(4, '2023-10-25 16:00:00', 'Pending', 'NEWCUST5');
INSERT INTO order_items (order_id, product_sku, quantity, price_per_unit) VALUES
(1, 'ELEC-LAP-1001', 1, 1299.99),
(1, 'HOME-KIT-050', 1, 85.00), -- Price slightly different at time of order
(2, 'BOOK-FIC-205A', 2, 19.95),
(3, 'HOME-KIT-050', 1, 89.50),
(4, 'BOOK-NF-110B', 1, 35.00),
(5, 'ELEC-CAM-300', 1, 249.00);
Tasks for Variant 4:
- Customer Full Name: Select
customer_idand display the customer’s full name by concatenatingfirst_nameandlast_namewith a space in between. Alias the result asfull_name. - Standardized Email Addresses: Display the
customer_idandemailaddress for all customers, ensuring theemailis entirely in lowercase. Alias this asstandard_email. - Customer Membership Duration: Calculate how long each customer has been registered (since
registration_date) as ofCURRENT_DATE. Displaycustomer_id,registration_date, and the duration usingAGE(), aliased asmembership_duration. - Cleaned Postal Codes: Display the
customer_idandpostal_code. If thepostal_codeis not NULL, show it after removing any leading or trailing spaces; otherwise, show ‘N/A’. Alias this ascleaned_postal_code. (Hint: UseTRIMandCOALESCE). - Product SKU Analysis: For each product, extract the category part (before the first ‘-‘) and the core code part (between the first and second ‘-‘). Display
product_sku, the extractedsku_category, andsku_core. (Hint: UseSUBSTRINGand potentiallyPOSITIONor fixed lengths if the pattern is consistent). Simplified for tutorial scope: Assume first part is 4 chars, second is 3 chars. ExtractSUBSTRING(product_sku FROM 1 FOR 4)assku_category_prefixandSUBSTRING(product_sku FROM 6 FOR 3)assku_type_prefix. - Product Pricing Tiers: Display
product_name,unit_price, and a calculatedprice_tier. The tier should be ‘Budget’ if price < $50, ‘Mid-Range’ if price is $50 to $250 (inclusive), and ‘Premium’ if price > $250. Use aCASEstatement. - Order Item Total Value: For each item in
order_items, calculate the total value (quantity * price_per_unit). Displayitem_id,order_id,product_sku, and the calculateditem_total. - Days Since Order: For each order, calculate the number of full days that have passed since the
order_date(ignore time part for simplicity). Displayorder_id,order_date, anddays_passed. (Hint:CURRENT_DATE - CAST(order_date AS DATE)). - Unit Price Rounded: Display
product_nameandunit_price, along with theunit_pricerounded to the nearest whole dollar. Alias this asrounded_price. - Minimum Shipping Charge: Display
product_nameandunit_price. Calculate a hypothetical minimum shipping charge by rounding theunit_priceUP to the nearest dollar (CEIL). Alias this asmin_ship_charge_base. - Order Status Display: Display
order_idandorder_status. Create a columnis_processingthat showsTRUEif theorder_statusis ‘Pending’, andFALSEotherwise. (Hint: UseCASEor a boolean expression). - Order Placement Hour: Extract the hour (0-23) from the
order_datefor each order. Displayorder_id,order_date, andorder_hour. - Absolute Price Difference from $100: For each product, calculate the absolute difference between its
unit_priceand $100. Displayproduct_name,unit_price, andabs_diff_from_100. - Formatted Product Price String: Display the
product_nameandunit_price. Create a string representation of the price prefixed with ‘$’. Alias this asformatted_price. (e.g., ‘$1299.99’). Use'$' || unit_price::VARCHAR. - Padded Order ID: Display the
order_idformatted as a 10-digit string with leading zeros (e.g., 1 becomes ‘0000000001’). Alias this asformatted_order_id. UseLPAD.
Variant 5: Event Management System
Scenario: You are managing a database for an event organizing company, tracking events, venues, attendee registrations, and payments.
Database Schema:
-- Drop tables if they exist (optional)
-- DROP TABLE IF EXISTS registrations;
-- DROP TABLE IF EXISTS attendees;
-- DROP TABLE IF EXISTS events;
-- DROP TABLE IF EXISTS venues;
-- 1. Create the 'venues' table
CREATE TABLE venues (
venue_id SERIAL PRIMARY KEY,
venue_name VARCHAR(100) NOT NULL UNIQUE, -- For UPPER(), LENGTH()
address VARCHAR(255),
city VARCHAR(100),
capacity INTEGER CHECK (capacity > 0), -- For MOD(), numeric ops
booking_cost NUMERIC(8, 2), -- For ROUND(), CEIL(), ABS()
contact_phone VARCHAR(20) -- e.g., ' 123-456-7890 ', for TRIM(), REPLACE()
);
-- 2. Create the 'events' table
CREATE TABLE events (
event_id SERIAL PRIMARY KEY,
event_name VARCHAR(150) NOT NULL, -- For SUBSTRING()
venue_id INTEGER REFERENCES venues(venue_id),
event_type VARCHAR(50), -- e.g., 'Conference', 'Workshop', 'Webinar', 'Gala'
start_datetime TIMESTAMP NOT NULL, -- For EXTRACT(), AGE(), INTERVAL
end_datetime TIMESTAMP, -- Can be NULL (e.g., single day event), check start/end duration
base_ticket_price NUMERIC(7, 2) DEFAULT 0.00 -- For CASE, NULLIF
);
-- 3. Create the 'attendees' table
CREATE TABLE attendees (
attendee_id SERIAL PRIMARY KEY,
first_name VARCHAR(50) NOT NULL,
last_name VARCHAR(50) NOT NULL,
email VARCHAR(100) UNIQUE NOT NULL, -- For LOWER()
signup_date DATE DEFAULT CURRENT_DATE, -- For AGE()
company_name VARCHAR(100) -- Allows NULL, for COALESCE
);
-- 4. Create the 'registrations' table
CREATE TABLE registrations (
registration_id SERIAL PRIMARY KEY,
event_id INTEGER NOT NULL REFERENCES events(event_id),
attendee_id INTEGER NOT NULL REFERENCES attendees(attendee_id),
registration_time TIMESTAMP DEFAULT NOW(), -- For EXTRACT(), AGE()
ticket_type VARCHAR(20) DEFAULT 'Standard', -- e.g., 'Standard', 'VIP', 'EarlyBird'
final_price NUMERIC(7, 2), -- Price paid, could differ from base price
payment_status VARCHAR(15) -- e.g., 'Paid', 'Pending', 'Refunded', NULL
);
-- Sample Data Insertion --
INSERT INTO venues (venue_name, capacity, booking_cost, contact_phone) VALUES
('Grand Hall', 500, 5000.00, ' 111-222-3333 '),
('Convention Center East Wing', 1500, 12000.50, '444-555-6666'),
('Cozy Corner Room', 50, 800.75, NULL), -- NULL phone
('Online Platform', 10000, 200.00, ' N/A ');
INSERT INTO events (event_name, venue_id, event_type, start_datetime, end_datetime, base_ticket_price) VALUES
('Annual Tech Conference 2024', 2, 'Conference', '2024-09-10 09:00:00', '2024-09-12 17:00:00', 499.00),
('Data Science Workshop', 1, 'Workshop', '2024-07-15 10:00:00', '2024-07-15 16:30:00', 150.00),
('Introduction to SQL Webinar', 4, 'Webinar', '2024-05-20 14:00:00', NULL, 0.00), -- Free event, NULL end time
('Charity Gala Dinner', 1, 'Gala', '2024-11-01 19:00:00', '2024-11-01 23:00:00', 250.50);
INSERT INTO attendees (first_name, last_name, email, company_name) VALUES
('Alice', 'Wonder', 'alice.w@example.com', 'Curious Inc.'),
('Bob', 'Marley', 'bob.m@example.com', NULL), -- NULL company
('Charlie', 'Day', 'charlie.d@example.com', 'Paddy''s Pub'),
('Diana', 'Prince', 'diana.p@example.com', 'Themyscira Exports');
INSERT INTO registrations (event_id, attendee_id, registration_time, ticket_type, final_price, payment_status) VALUES
(1, 1, '2024-03-15 10:00:00', 'EarlyBird', 399.00, 'Paid'),
(1, 2, '2024-04-01 11:30:00', 'Standard', 499.00, 'Paid'),
(2, 3, '2024-06-10 16:00:00', 'Standard', 150.00, 'Pending'),
(3, 1, '2024-05-01 09:00:00', 'Standard', 0.00, 'Paid'), -- Free event
(4, 4, '2024-09-01 14:20:00', 'VIP', 350.00, 'Paid'),
(2, 4, '2024-07-01 13:00:00', 'Standard', 150.00, NULL); -- NULL payment status
Tasks for Variant 5:
- Attendee Full Name: Select
attendee_idand display the attendee’s full name by concatenatingfirst_nameandlast_namewith a space. Alias the result asfull_name. - Cleaned Venue Phone: Display the
venue_nameandcontact_phone. Show thecontact_phoneafter removing all spaces and hyphens. If the phone is NULL or ‘ N/A ‘, display ‘Not Available’. Alias this ascleaned_phone. (Hint: UseREPLACE,TRIM,COALESCE). - Event Duration: Calculate the duration of each event (
end_datetime-start_datetime). Ifend_datetimeis NULL, display NULL. Displayevent_name,start_datetime,end_datetime, and the calculatedduration(as an INTERVAL). - Time Since Registration: For each registration, calculate how long ago it occurred (
registration_time) relative toNOW(). Displayregistration_id,registration_time, and the duration usingAGE(), aliased asregistration_age. - Event Pricing Category: Display
event_nameandbase_ticket_price. Create aprice_categoryusingCASE: ‘Free’ if price is 0, ‘Affordable’ if price > 0 and <= 100, ‘Standard’ if price > 100 and <= 300, ‘Premium’ if price > 300. - Standardized Attendee Emails: Display the
attendee_id,first_name, andemail, ensuring theemailis entirely in lowercase. Alias this asstandard_email. - Venue Capacity Check: Display
venue_nameandcapacity. Add a columnis_large_venuewhich is TRUE if thecapacityis greater than 1000, and FALSE otherwise. - Event Start Day: Extract the day of the week (e.g., ‘Monday’, ‘Tuesday’) from the
start_datetimefor each event. Displayevent_name,start_datetime, andstart_day. (Hint: UseTO_CHARwithEXTRACT(DOW FROM ...)might be needed for the name, or just show the DOW number fromEXTRACT). Let’s stick to the number:EXTRACT(DOW FROM start_datetime) AS start_dow(0=Sun, 6=Sat in PG). - Venue Cost Rounded Up: Display
venue_nameandbooking_cost. Calculate the cost rounded UP to the nearest $100. Alias this ascost_ceil_100. (Hint:CEIL(booking_cost / 100.0) * 100). - Attendee Company Display: Display
attendee_id,first_name. UseCOALESCEto show thecompany_name; if it’s NULL, display ‘Individual Attendee’. Alias this asaffiliation. - Absolute Price Difference from Base: For registrations, calculate the absolute difference between the
final_priceand the event’sbase_ticket_price(requires joiningregistrationsandevents). Displayregistration_id,base_ticket_price,final_price, andprice_difference. - Identify Pending Payments: Use
NULLIFto return theregistration_idonly if thepayment_statusis NOT ‘Paid’. Otherwise, return NULL. Displayregistration_id,payment_status, and the result asunpaid_registration_id. - Short Event Name: Display the
event_idand the first 30 characters of theevent_name. Alias this asshort_event_name. UseSUBSTRING. - Padded Venue ID: Display the
venue_idformatted as a 5-digit string with leading zeros. Alias this asformatted_venue_id. UseLPAD. - Days Until Event Start: For events starting in the future, calculate the number of days from
CURRENT_DATEuntilstart_datetime. Displayevent_name,start_datetime, anddays_until_start. Handle events in the past (result might be negative or filter them out). Usestart_datetime::DATE - CURRENT_DATE.
Variant 6: Blog Platform
Scenario: You are managing the database for a multi-user blog platform, tracking users, posts, comments, and categories.
Database Schema:
-- Drop tables if they exist (optional)
-- DROP TABLE IF EXISTS comments;
-- DROP TABLE IF EXISTS posts;
-- DROP TABLE IF EXISTS categories;
-- DROP TABLE IF EXISTS users;
-- 1. Create the 'users' table
CREATE TABLE users (
user_id SERIAL PRIMARY KEY,
username VARCHAR(30) UNIQUE NOT NULL, -- For LENGTH(), LOWER()
email VARCHAR(100) UNIQUE NOT NULL, -- For LOWER()
full_name VARCHAR(100), -- For CONCAT (if split needed) or just display
join_date DATE NOT NULL DEFAULT CURRENT_DATE, -- For AGE(), EXTRACT()
profile_bio TEXT -- Allows NULL, for COALESCE, LENGTH()
-- password_hash VARCHAR(255) NOT NULL -- Not used in tasks
);
-- 2. Create the 'categories' table
CREATE TABLE categories (
category_id SERIAL PRIMARY KEY,
category_name VARCHAR(50) UNIQUE NOT NULL, -- For UPPER(), REPLACE()
slug VARCHAR(60) UNIQUE -- e.g., 'data-science-basics', for LOWER(), REPLACE()
);
-- 3. Create the 'posts' table
CREATE TABLE posts (
post_id SERIAL PRIMARY KEY,
author_id INTEGER NOT NULL REFERENCES users(user_id),
category_id INTEGER REFERENCES categories(category_id),
title VARCHAR(200) NOT NULL, -- For SUBSTRING()
content TEXT, -- For LENGTH()
publish_datetime TIMESTAMP, -- Allows NULL for drafts. For EXTRACT(), AGE(), INTERVAL
last_updated TIMESTAMP DEFAULT NOW(),
status VARCHAR(15) DEFAULT 'Draft', -- 'Draft', 'Published', 'Archived' - For CASE, NULLIF
word_count INTEGER -- For MOD(), CEIL(), numeric ops
);
-- 4. Create the 'comments' table
CREATE TABLE comments (
comment_id SERIAL PRIMARY KEY,
post_id INTEGER NOT NULL REFERENCES posts(post_id),
commenter_id INTEGER REFERENCES users(user_id), -- NULL if commenter is anonymous/not logged in
commenter_name VARCHAR(50), -- Used if commenter_id is NULL
comment_text TEXT NOT NULL,
comment_datetime TIMESTAMP DEFAULT NOW(), -- For EXTRACT(), AGE()
parent_comment_id INTEGER REFERENCES comments(comment_id) -- For threaded comments (NULL if top-level)
);
-- Sample Data Insertion --
INSERT INTO users (username, email, full_name, join_date, profile_bio) VALUES
('john_doe', 'john.doe@blog.com', 'John Doe', '2022-01-10', 'Tech enthusiast and blogger.'),
('jane_smith', 'Jane.Smith@blog.com', 'Jane Smith', '2022-03-15', NULL), -- NULL bio
('bob_coder', 'bob@coder.net', 'Bob Coder', '2023-05-01', 'Software developer sharing tips.'),
('reader_x', 'readerX@mail.com', NULL, '2023-10-01', NULL); -- No full name, no bio
INSERT INTO categories (category_name, slug) VALUES
('Technology', 'technology'),
('Data Science', 'data-science'),
('Tutorials', 'tutorials'),
(' Opinion Pieces ', 'opinion-pieces'); -- Slug needs generating/cleaning
INSERT INTO posts (author_id, category_id, title, content, publish_datetime, status, word_count) VALUES
(1, 1, 'The Future of AI', 'AI is evolving rapidly...', '2023-06-01 10:00:00', 'Published', 1250),
(3, 2, 'Introduction to PostgreSQL Functions', 'This post covers several useful SQL functions...', '2023-07-15 14:30:00', 'Published', 1800),
(1, 3, 'Setting Up a Python Dev Environment', 'Step-by-step guide...', NULL, 'Draft', 950), -- Draft, no publish date
(2, 4, 'Why Static Sites Are Great', 'My thoughts on static site generators...', '2023-09-01 11:00:00', 'Published', 780),
(3, 1, 'Old Tech Thoughts', 'Some musings on older tech...', '2022-11-20 09:00:00', 'Archived', 600); -- Archived
INSERT INTO comments (post_id, commenter_id, commenter_name, comment_text, comment_datetime) VALUES
(1, 2, NULL, 'Great overview!', '2023-06-01 11:00:00'),
(2, 1, NULL, 'Very helpful, thanks Bob!', '2023-07-16 09:15:00'),
(1, NULL, 'Guest User', 'I disagree with point 2.', '2023-06-02 15:00:00'), -- Anonymous comment
(4, 3, NULL, 'Nice points, Jane!', '2023-09-01 12:30:00'),
(2, 4, NULL, 'Where can I learn more?', '2023-10-05 10:00:00');
Tasks for Variant 6:
- Username Length Check: Display the
user_idandusername. Also show the length of eachusername, aliased asusername_length. - Category Slug Generation: Display
category_name. Generate a potentialslugby convertingcategory_nameto lowercase, removing leading/trailing spaces, and replacing remaining spaces with hyphens. Alias this asgenerated_slug. (UseLOWER,TRIM,REPLACE). - User Account Age: Calculate how long each user has been registered (since
join_date) as ofCURRENT_DATE. Displayusername,join_date, and the duration usingAGE(), aliased asaccount_age. - Post Excerpt: For each post, display the
post_id,title, and the first 150 characters of thecontent. If the content is longer than 150 characters, append ‘…’. Alias this aspost_excerpt. (Hint: UseSUBSTRING,LENGTH,CASE,CONCAT/||). - Standardized User Emails: Display the
user_id,username, andemail, ensuring theemailis entirely in lowercase. Alias this asstandard_email. - Post Publication Age: For published posts (
publish_datetimeis NOT NULL), calculate how long ago they were published relative toNOW(). Displaypost_id,title,publish_datetime, and the duration usingAGE(), aliased astime_since_publish. - Comment Time Analysis: For each comment, extract the year, month, and hour from
comment_datetime. Displaycomment_id,comment_datetime,comment_year,comment_month, andcomment_hour. - Post Visibility Status: Display
post_id,title, andstatus. Create a columnis_visibleusingCASE: TRUE ifstatusis ‘Published’, FALSE otherwise. - Post Word Count Parity: Display
post_id,title, andword_count. Determine if theword_countis ‘Even’ or ‘Odd’. Alias this asword_count_parity. (Hint: UseMODor%). - User Bio Display: Display
usernameandprofile_bio. UseCOALESCEto show ‘No bio provided’ ifprofile_biois NULL or an empty string. (Hint:COALESCE(NULLIF(TRIM(profile_bio), ''), 'No bio provided')). - Absolute Word Count Deviation: Calculate the absolute difference between each post’s
word_countand a target length of 1000 words. Displaypost_id,word_count, andabs_diff_from_1000. - Identify Non-Published Posts: Use
NULLIFto return thepost_idif the poststatusis ‘Draft’ or ‘Archived’. Otherwise, return NULL. Displaypost_id,status, and the result asnon_published_post_id. - Estimated Reading Time: Calculate an estimated reading time in minutes by dividing
word_countby 200 (average words per minute) and rounding the result UP to the nearest whole number. Displaypost_id,word_count, andestimated_read_minutes. (UseCEIL). - Padded User ID: Display the
user_idformatted as a 7-digit string with leading zeros. Alias this asformatted_user_id. UseLPAD. - Commenter Identification: Display
comment_idandcomment_text. Show the commenter’s identity: ifcommenter_idis not NULL, display ‘User: ‘ followed by thecommenter_id(cast to VARCHAR). Ifcommenter_idis NULL, display ‘Guest: ‘ followed bycommenter_name. Alias this ascommenter_identity. (UseCASEandCOALESCEor nestedCASE).
Submission Instructions
- Create a new Google Document. Example
- Submit Your Google Doc Link: Google Sheet