diff --git a/FunctionInpostgres.sql b/FunctionInpostgres.sql new file mode 100644 index 0000000..cebbfc4 --- /dev/null +++ b/FunctionInpostgres.sql @@ -0,0 +1,45 @@ +-- Create a function that takes a student's score and returns a grade (e.g., A, B, C, F) +CREATE or replace FUNCTION grab_grade(score numeric) +RETURNS TEXT +LANGUAGE plpgsql +as +$$ + +BEGIN + IF score >= 90 THEN + RETURN 'A'; + ELSIF score >= 80 THEN + RETURN 'B'; + ELSIF score >= 70 THEN + RETURN 'C'; + ELSE + RETURN 'F'; + END IF; +END + +$$ + +SELECT name, score, grab_grade(score) FROM students; + +select * from students + +select * from departments + + +-- Create a function that returns the full name and department of a student by ID. + + +SELECT students.name as student_name, departments.name as department_name +FROM students +JOIN departments ON departments.id = students.department_id; + +CREATE or replace FUNCTION dpt_fn() +RETURNS TABLE(student_name TEXT, department_name TEXT) +LANGUAGE sql +AS +$$ +SELECT students.name as student_name, departments.name as department_name FROM students +JOIN departments ON departments.id = students.department_id; +$$ + +SELECT * FROM dpt_fn(); \ No newline at end of file diff --git a/dateAndGroupingTask.sql b/dateAndGroupingTask.sql new file mode 100644 index 0000000..cfb6866 --- /dev/null +++ b/dateAndGroupingTask.sql @@ -0,0 +1,114 @@ +CREATE TABLE departments ( + id SERIAL PRIMARY KEY, + name VARCHAR(50) NOT NULL +); + +CREATE TABLE students ( + id SERIAL PRIMARY KEY, + name VARCHAR(50) NOT NULL, + age INTEGER NOT NULL, + score NUMERIC(10,4) , + department_id INTEGER NOT NULL REFERENCES departments(id) +); + + +CREATE TABLE course_enrollment ( + id SERIAL PRIMARY KEY, + student_id INTEGER NOT NULL REFERENCES students(id), + course_title VARCHAR(100) NOT NULL, + enroll_on DATE NOT NULL +); + +INSERT INTO departments (name) +VALUES + ('CSE'), + ('EEE'), + ('BBA'), + ('ME'), + ('Civil'); + + +INSERT INTO students (name, age, score, department_id) +VALUES +('Alice', 20, 91.5, 1), + ('Bob', 21, 78.0, 2), + ('Charlie', 22, 84.3, 1), + ('David', 20, 65.7, 3), + ('Eve', 23, 88.9, 2), + ('Frank', 24, 92.4, 4), + ('Grace', 21, NULL, 5), + ('Rachel', 22, 85.2, 1), + ('Steve', 24, 60.0, 3), + ('Trudy', 20, NULL, 2), -- score is NULL + ('Uma', 21, 92.7, 1), + ('Victor', 23, 48.5, 4), + ('Wendy', 25, 75.3, 5), + ('Xander', 26, 88.8, 3), + ('Yasmine', 22, 79.5, 2), + ('Zane', 24, NULL, 4), -- score is NULL + ('Abigail', 20, 66.6, 5), + ('Heidi', 22, 79.2, 1), + ('Ivan', 20, 55.0, 3), + ('Judy', 25, 89.5, 2), + ('Kevin', 23, 95.0, 1), + ('Laura', 24, 70.0, 4), + ('Mallory', 21, 67.8, 5), + ('Nathan', 22, 82.6, 2), + ('Olivia', 20, NULL, 3), -- Another NULL score + ('Peter', 26, 74.1, 4), + ('Quinn', 23, 90.3, 1); + +INSERT INTO course_enrollment (student_id, course_title, enroll_on) +VALUES +(1, 'Database Systems', '2024-01-15'), + (1, 'Operating Systems', '2024-02-10'), + (2, 'Circuit Analysis', '2024-03-12'), + (3, 'Algorithms', '2024-04-01'), + (4, 'Marketing Basics', '2024-02-20'), + (6, 'Thermodynamics', '2024-05-01'), + (7, 'Cybersecurity Fundamentals', '2023-11-15'), + (8, 'Data Analytics', '2024-01-20'), + (9, 'Digital Marketing', '2023-12-05'), + (10, 'Machine Learning', '2024-03-10'), + (11, 'Thermal Engineering', '2024-04-18'), + (12, 'Fluid Mechanics', '2023-10-08'), + (13, 'Econometrics', '2024-05-21'), + (14, 'Intro to AI', '2024-02-28'), + (15, 'Project Management', '2024-03-02'), + (16, 'Database Systems', '2024-04-25'), + (17, 'Software Engineering', CURRENT_DATE); + +drop Table course_enrollment; +drop Table students; +drop Table departments; + +-- Query Practice & Subqueries (Based on 10-1 to 10-3) +-- Retrieve all students who scored higher than the average score. +-- SELECT avg(score) from students; +SELECT* from students +WHERE score > (SELECT avg(score) from students); + +-- Find students whose age is greater than the average age of all students. +-- SELECT avg(age) from students; +SELECT * FROM students +WHERE age > (SELECT avg(age) from students); + +-- Get names of students who are enrolled in any course (use IN with subquery). + +SELECT * from students; +SELECT * from students +WHERE id IN (SELECT student_id FROM course_enrollment); + +-- Retrieve departments with at least one student scoring above 90 (use EXISTS). + +SELECT * FROM departments +WHERE EXISTS ( + SELECT 1 + FROM students + WHERE students.department_id = departments.id + AND students.score > 90 +); + +SELECT* from students; +SELECT* from departments; +SELECT* from course_enrollment \ No newline at end of file diff --git a/functionProcedures.sql b/functionProcedures.sql new file mode 100644 index 0000000..7d4fd81 --- /dev/null +++ b/functionProcedures.sql @@ -0,0 +1,105 @@ + +/* + @Procedural Approach: + 1. Language Support: Supports procedural languages like PL/pgSQL, PL/Perl, PL/Python, etc. + 2. Complex Logic: Allows for complex logic using control structures like loops, conditionals, and exception handling. + 3. Variable Support: Supports variable declarations and manipulation within the procedural code. + 4. Stored Procedures/Functions: Provides the ability to create stored procedures or functions, + + @Non-Procedural Approach: + 1. Declarative Queries: Focuses on writing declarative SQL queries to retrieve, insert, update, or delete data from the database. + 2. Simplicity: Emphasizes simplicity by expressing operations in terms of what data is needed. + 3. SQL Functions: Supports SQL functions, which are single SQL statements that return a value or set of values. + 4. Performance: Can sometimes offer better performance for simple operations due to the optimized query execution plans generated by the database engine. +*/ + +SELECT * from employees; + +SELECT count(*) FROM employees + +CREATE Function emp_count() +RETURNS INT +LANGUAGE sql -- here can be plpgsql/plperl/PL/Python or etc for PROCEDURAL +AS +$$ +-- here will be the function body +SELECT count(*) FROM employees +$$ + +SELECT emp_count(); + +CREATE or REPLACE function delete_emp() +RETURNS void +LANGUAGE SQL +AS +$$ +DELETE FROM employees WHERE employee_id = 30; +$$ + +SELECT delete_emp(); + + +CREATE OR replace FUNCTION delete_emp_by_id(p_emp_id INT) +RETURNS void +LANGUAGE SQL +AS +$$ +DELETE FROM employees WHERE employee_id = p_emp_id; +$$ + +SELECT delete_emp_by_id(29); + +CREATE PROCEDURE remove_emp() +LANGUAGE plpgsql +AS +$$ +BEGIN +-- here we can write multiple sql queries or one single queries +-- here will exist the works/action that we want to do using procedure. +DELETE FROM employees WHERE employee_id = 28; +END +$$ + +CALL remove_emp() + +CREATE PROCEDURE remove_emp_var() +LANGUAGE plpgsql +AS +$$ +DECLARE +test_var INT; +BEGIN +SELECT employee_id INTO test_var FROM employees WHERE employee_id = 26; +DELETE FROM employees WHERE employee_id = test_var; +END +$$ + +CALL remove_emp_var() + +SELECT * FROM employees + + + +CREATE PROCEDURE remove_emp_by_p(p_employee_id int) +LANGUAGE plpgsql +AS +$$ + +DECLARE +test_var INT; +-- variable declared. + +BEGIN +SELECT employee_id INTO test_var FROM employees WHERE employee_id = p_employee_id; + -- we are setting the id to the variable test_var and then we are doing the operation +DELETE FROM employees WHERE employee_id = test_var; + +RAISE NOTICE 'Employee Removed Successfully'; +-- this will give a notice if deleted. +END + +$$; + +CALL remove_emp_by_p(24) + +SELECT * FROM employees \ No newline at end of file diff --git a/indexingInPostgres.sql b/indexingInPostgres.sql new file mode 100644 index 0000000..0c8a609 --- /dev/null +++ b/indexingInPostgres.sql @@ -0,0 +1,17 @@ +-- Active: 1747459510114@@localhost@5432@ph_2 +CREATE INDEX idx_score ON students(score); + +CREATE INDEX idx_enrollment_composite ON course_enrollment(student_id, enroll_on); + +SELECT * FROM course_enrollment + + +EXPLAIN ANALYZE +SELECT * +FROM students +WHERE score > 80; + +EXPLAIN ANALYZE +SELECT * +FROM course_enrollment +WHERE student_id = 3 AND enroll_on > '2024-01-01'; diff --git a/practiecBySazid.sql b/practiecBySazid.sql new file mode 100644 index 0000000..f50e61e --- /dev/null +++ b/practiecBySazid.sql @@ -0,0 +1,154 @@ +-- Active: 1747459510114@@localhost@5432@ph_2 + +CREATE Table orders( +order_id SERIAL PRIMARY KEY, +customer_id INTEGER, +order_date DATE, +total_amount DECIMAL(10,2) +) + +INSERT INTO orders(customer_id, order_date, total_amount) VALUES +(101, '2025-05-01', 199.99), +(102, '2025-05-02', 89.50), +(103, '2025-05-03', 145.00), +(104, '2025-05-04', 320.75), +(101, '2025-05-05', 25.99), +(105, '2025-05-06', 470.00), +(102, '2025-05-07', 129.49), +(106, '2025-05-08', 250.00), +(107, '2025-05-09', 78.90), +(108, '2025-05-10', 199.00), +(102, '2024-03-07', 129.49), +(106, '2024-02-08', 250.00), +(107, '2024-01-09', 78.90), +(108, '2024-06-10', 199.00); + +-- Find customers who have placed more than 2 orders and calculate the total amount spent by each of these customers. + +SELECT customer_id, count(*) as order_qty, sum(total_amount) from orders +GROUP BY customer_id +HAVING count(order_id) >2; + +-- Find the total amount of orders placed each month in the year 2025. + +SELECT extract(month from order_date) as all_months, count(*) as order_qty FROM orders +WHERE EXTRACT(YEAR FROM order_date) = 2025 +GROUP BY all_months + + +-- Understanding sub queries + +CREATE TABLE employees ( + employee_id SERIAL PRIMARY KEY, + employee_name VARCHAR(50) NOT NULL, + department_name VARCHAR(50), + salary DECIMAL(10, 2), + hire_date DATE +); + + +INSERT INTO employees (employee_name, department_name, salary, hire_date) VALUES + ('John Doe', 'HR', 60000.00, '2022-01-10'), + ('Jane Smith', 'Marketing', 75000.50, '2021-05-22'), + ('Bob Johnson', 'Finance', 80000.75, '2020-11-15'), + ('Alice Williams', 'IT', 90000.25, '2019-08-03'), + ('David Lee', 'Sales', 65000.50, '2020-03-18'), + ('Sara Brown', 'Engineering', 70000.00, '2021-09-28'), + ('Mike Miller', 'Customer Support', 55000.75, '2022-02-05'), + ('Emily Davis', 'Administration', 95000.00, '2018-12-12'), + ('Chris Wilson', 'Research', 72000.50, '2020-06-30'), + ('Amy White', 'Quality Assurance', 68000.25, '2021-11-09'), + ('John Johnson', 'HR', 62000.00, '2022-01-15'), + ('Jessica Thompson', 'Marketing', 78000.50, '2021-06-05'), + ('Michael Harris', 'Finance', 85000.75, '2020-11-25'), + ('Emma Martinez', 'IT', 92000.25, '2019-09-15'), + ('James Taylor', 'Sales', 67000.50, '2020-04-08'), + ('Sophia Anderson', 'Engineering', 72000.00, '2021-10-10'), + ('William Jackson', 'Customer Support', 56000.75, '2022-02-10'), + ('Olivia Nelson', 'Administration', 97000.00, '2018-12-20'), + ('Daniel White', 'Research', 73000.50, '2020-07-05'), + ('Ava Wilson', 'Quality Assurance', 69000.25, '2021-11-15'), + ('Matthew Brown', 'HR', 63000.00, '2022-01-20'), + ('Emily Garcia', 'Marketing', 76000.50, '2021-06-15'), + ('Christopher Allen', 'Finance', 86000.75, '2020-12-05'), + ('Madison Hall', 'IT', 93000.25, '2019-09-25'), + ('Andrew Cook', 'Sales', 68000.50, '2020-04-18'), + ('Abigail Torres', 'Engineering', 73000.00, '2021-10-20'), + ('Ethan Murphy', 'Customer Support', 57000.75, '2022-02-15'), + ('Ella King', 'Administration', 98000.00, '2018-12-28'), + ('Nathan Rivera', 'Research', 74000.50, '2020-07-15'), + ('Mia Roberts', 'Quality Assurance', 70000.25, '2021-11-20'); + + +SELECT * FROM employees; +SELECT department_name, max(salary) FROM employees GROUP BY department_name HAVING department_name = 'HR'; + +SELECT * FROM employees WHERE salary > (SELECT max(salary) FROM employees WHERE department_name = 'HR'); + +-- subqueries with select + +SELECT *, (SELECT sum(salary) FROM employees) as salary_sum FROM employees ; + +DROP Table employees + +CREATE TABLE departments ( + department_id SERIAL PRIMARY KEY, + department_name VARCHAR(100) +); + +CREATE TABLE employees ( + employee_id SERIAL PRIMARY KEY, + employee_name VARCHAR(100), + department_id INT REFERENCES departments(department_id), + salary NUMERIC, + hire_date DATE +); + +INSERT INTO departments (department_name) VALUES + ('Engineering'), + ('Human Resources'), + ('Marketing'), + ('Sales'), + ('Finance'); + +INSERT INTO employees (employee_name, department_id, salary, hire_date) VALUES + ('Alice', 1, 90000, '2020-03-15'), + ('Bob', 1, 85000, '2021-07-01'), + ('Charlie', 1, 95000, '2019-11-23'), + ('David', 2, 60000, '2021-01-10'), + ('Eva', 2, 58000, '2020-05-20'), + ('Frank', 3, 72000, '2022-02-28'), + ('Grace', 3, 75000, '2018-06-30'), + ('Hannah', 4, 67000, '2021-12-05'), + ('Ian', 4, 68000, '2022-01-11'), + ('Jack', 5, 80000, '2019-09-15'); + +DROP TABLE departments; +DROP TABLE employees; + +SELECT department_name FROM (SELECT * FROM employees natural JOIN departments) as joined_table + +; + +SELECT d.department_name, s.total_salary +FROM departments d +JOIN ( + SELECT department_id, SUM(salary) AS total_salary + FROM employees + GROUP BY department_id +) s ON d.department_id = s.department_id; + +SELECT * FROM(SELECT department_name, sum(salary) FROM employees GROUP BY department_name) as sum_dept_salary; + +SELECT department_name FROM(SELECT department_name, sum(salary) FROM employees GROUP BY department_name) as sum_dept_salary; + +CREATE VIEW test_view AS +SELECT employee_name, salary, department_name +FROM employees +WHERE department_name IN ( + SELECT department_name + FROM employees + WHERE department_name LIKE '%R%' +); + +SELECT * FROM test_view; \ No newline at end of file diff --git a/triggersInPostgres.sql b/triggersInPostgres.sql new file mode 100644 index 0000000..887d794 --- /dev/null +++ b/triggersInPostgres.sql @@ -0,0 +1,86 @@ +-- Triggers in PostgreSQL (Based on 10-7) +-- Create a trigger that automatically logs enrollment when a student is added to course_enrollments. + +-- Log table +CREATE TABLE log_table ( + id SERIAL PRIMARY KEY, + student_id INTEGER NOT NULL REFERENCES students(id), + course_title TEXT NOT NULL, + department_id INTEGER NOT NULL REFERENCES departments(id), + action TEXT, + action_time TIMESTAMP DEFAULT NOW() +); + + +-- Trigger function +CREATE OR REPLACE FUNCTION save_log() +RETURNS TRIGGER +LANGUAGE plpgsql +AS $$ +DECLARE + dept_id INTEGER; +BEGIN + -- Get department of student + SELECT department_id INTO dept_id + FROM students + WHERE id = NEW.student_id; + + -- Insert log row + INSERT INTO log_table (student_id, course_title, department_id, action) + VALUES (NEW.student_id, NEW.course_title, dept_id, 'ENROLLED'); + + RETURN NEW; +END; +$$; + +CREATE TRIGGER save_enrolled_student +AFTER INSERT ON course_enrollment +FOR EACH ROW +EXECUTE FUNCTION save_log(); + + +INSERT INTO course_enrollment (student_id, course_title, enroll_on) +VALUES +(2, 'Database Systems', '2024-01-15'); + +SELECT * FROM log_table + +-- Add a trigger that sets the score to 0 if a new student record is added without a score. + + +-- Trigger function +-- Trigger function +CREATE OR REPLACE FUNCTION set_default_score() +RETURNS TRIGGER +LANGUAGE plpgsql +AS $$ +BEGIN + -- Check if NEW.score is NULL + IF NEW.score IS NULL THEN + NEW.score := 0; + END IF; + + RETURN NEW; +END; +$$; + +-- Trigger +CREATE TRIGGER set_score_if_null +BEFORE INSERT ON students +FOR EACH ROW +EXECUTE FUNCTION set_default_score(); + +INSERT INTO students (name, age, score, department_id) +VALUES +('Shakil', 25,NULL, 1) + + + + + + +SELECT* from departments + +SELECT* from course_enrollment; + +SELECT* from students; \ No newline at end of file