0% found this document useful (0 votes)
21 views23 pages

Postgre SQL Advance Notes

This document provides comprehensive notes on PostgreSQL for interns, covering installation on various operating systems, types of SQL commands, and examples for creating databases, tables, and manipulating data. It details functions, operators, joins, and stored procedures, along with practical examples and tips for using pgAdmin. Additionally, it includes PostgreSQL equivalents for common SQL functions and emphasizes hands-on practice for better understanding.

Uploaded by

ceoviveksahu928
Copyright
© © All Rights Reserved
We take content rights seriously. If you suspect this is your content, claim it here.
Available Formats
Download as PDF, TXT or read online on Scribd
0% found this document useful (0 votes)
21 views23 pages

Postgre SQL Advance Notes

This document provides comprehensive notes on PostgreSQL for interns, covering installation on various operating systems, types of SQL commands, and examples for creating databases, tables, and manipulating data. It details functions, operators, joins, and stored procedures, along with practical examples and tips for using pgAdmin. Additionally, it includes PostgreSQL equivalents for common SQL functions and emphasizes hands-on practice for better understanding.

Uploaded by

ceoviveksahu928
Copyright
© © All Rights Reserved
We take content rights seriously. If you suspect this is your content, claim it here.
Available Formats
Download as PDF, TXT or read online on Scribd
You are on page 1/ 23

PostgreSQL Notes for Interns

Installation
Windows: Download the installer from the official PostgreSQL website and follow the setup
wizard. During installation, note the password and port (default: 5432) [1] .
Linux: Use your package manager, e.g., on Ubuntu:
sudo apt update
sudo apt install postgresql postgresql-contrib

macOS: Use the installer from the PostgreSQL site or Homebrew:


brew install postgresql

pgAdmin: A graphical tool installed with PostgreSQL for database management [2] [1] .

Types of SQL Commands


DDL (Data Definition Language): CREATE, ALTER, DROP (structure changes)
DML (Data Manipulation Language): INSERT, UPDATE, DELETE (data changes)
DQL (Data Query Language): SELECT (data retrieval)
DCL (Data Control Language): GRANT, REVOKE (permissions)
TCL (Transaction Control Language): COMMIT, ROLLBACK, SAVEPOINT

Create Database and Table


Create Database:
CREATE DATABASE mydb;

Create Table:
CREATE TABLE employees (
id SERIAL PRIMARY KEY,
name VARCHAR(100),
age INT,
salary NUMERIC(10,2)
);
Insert Data in the Table

INSERT INTO employees (name, age, salary)


VALUES ('John Doe', 30, 50000.00);

Insert multiple rows:

INSERT INTO employees (name, age, salary)


VALUES
('Alice', 28, 60000.00),
('Bob', 35, 70000.00);

Delete Rows and Columns


Delete Rows:
DELETE FROM employees WHERE id = 1;

Delete (Drop) Column:


ALTER TABLE employees DROP COLUMN salary;

Data Types and Constraints


Common Data Types:
INTEGER, SERIAL, VARCHAR(n), TEXT, DATE, TIMESTAMP, BOOLEAN, NUMERIC(p,s) [3] [4] .

Constraints:
PRIMARY KEY, UNIQUE, NOT NULL, CHECK, FOREIGN KEY

Example:

CREATE TABLE users (


user_id SERIAL PRIMARY KEY,
username VARCHAR(50) UNIQUE NOT NULL,
age INT CHECK (age >= 18)
);

Update Data

UPDATE employees SET salary = 55000 WHERE name = 'John Doe';


Update Data Using SQL Toolbar (pgAdmin)
Open pgAdmin, select the table, right-click → "View/Edit Data" → "All Rows".
Edit the data directly in the grid and click "Save".

Query Toolbar
In pgAdmin, use the "Query Tool" to write and execute SQL queries.

Altering Columns and Data Types


Add Column:
ALTER TABLE employees ADD COLUMN department VARCHAR(50);

Modify Data Type:


ALTER TABLE employees ALTER COLUMN age TYPE SMALLINT;

Importing CSV File


Through Command Line:
\copy employees(name, age, salary) FROM '/path/to/file.csv' DELIMITER ',' CSV HEADER;

Directly in pgAdmin:
Right-click the table → "Import/Export Data" → select CSV file and options.

Types of Operators in PostgreSQL


Type Examples

Arithmetic +, -, *, /, %

Comparison =, !=, <>, <, >, <=, >=

Logical AND, OR, NOT

Other IS NULL, IS NOT NULL, EXISTS

Set UNION, INTERSECT, EXCEPT


Comparison Operators
=, != or &lt;&gt;, &lt;, &gt;, &lt;=, &gt;=

Logical Operators
AND, OR, NOT

BETWEEN, LIKE, IN Operators


BETWEEN:
SELECT * FROM employees WHERE age BETWEEN 25 AND 35;

LIKE:
SELECT * FROM employees WHERE name LIKE 'A%';

IN:
SELECT * FROM employees WHERE department IN ('HR', 'IT');

Other Operators
IS NULL, IS NOT NULL

EXISTS

ANY, ALL

Set Operators
UNION, UNION ALL, INTERSECT, EXCEPT

Functions in SQL
Aggregate: COUNT(), SUM(), AVG(), MIN(), MAX()
String: UPPER(), LOWER(), LENGTH(), SUBSTRING()
Date/Time: NOW(), CURRENT_DATE, AGE()
Conditional: CASE, COALESCE()
Window: ROW_NUMBER(), RANK(), DENSE_RANK(), OVER()
String Functions
UPPER('abc') → 'ABC'
LOWER('ABC') → 'abc'
LENGTH('hello') → 5
SUBSTRING('abcdef', 2, 3) → 'bcd'

Date and Time Functions


NOW() → current timestamp
CURRENT_DATE → current date
AGE('2000-01-01') → interval from date

Conditional Functions
CASE:
SELECT name,
CASE
WHEN salary &gt; 60000 THEN 'High'
ELSE 'Low'
END AS salary_level
FROM employees;

COALESCE:
SELECT COALESCE(middle_name, 'N/A') FROM employees;

Window Functions
Used for calculations across a set of table rows related to the current row.
Examples: ROW_NUMBER(), RANK(), SUM() OVER (PARTITION BY department)

Joins
Join Type Description

INNER JOIN Rows with matching values in both tables

LEFT JOIN All rows from left table, matched rows from right table

RIGHT JOIN All rows from right table, matched rows from left table

FULL JOIN All rows from both tables

Example:
SELECT a.name, b.department_name
FROM employees a
INNER JOIN departments b ON a.department_id = b.id;

CTE (Common Table Expressions)


Temporary result set for complex queries.

WITH dept_count AS (
SELECT department, COUNT(*) AS num
FROM employees
GROUP BY department
)
SELECT * FROM dept_count WHERE num &gt; 5;

Subquery
Query inside another query.

SELECT name FROM employees WHERE salary &gt; (SELECT AVG(salary) FROM employees);

Stored Procedures and Functions


Function Example:
CREATE FUNCTION get_employee_count() RETURNS INT AS $$
BEGIN
RETURN (SELECT COUNT(*) FROM employees);
END;
$$ LANGUAGE plpgsql;

Stored Procedure Example:


CREATE PROCEDURE raise_salary(emp_id INT, amount NUMERIC)
LANGUAGE plpgsql
AS $$
BEGIN
UPDATE employees SET salary = salary + amount WHERE id = emp_id;
END;
$$;

Tip: Practice each command in pgAdmin or psql for hands-on learning [5] [2] [1] .

PostgreSQL Functions: Syntax, Explanation, and Examples
Below you'll find explanations, syntax, and practical examples for each major PostgreSQL
function category discussed previously.

1. Aggregate Functions
Aggregate functions perform calculations on sets of rows and return a single value.

Function Description Syntax Example

Returns average SELECT AVG(column) FROM SELECT AVG(salary) FROM


AVG()
value table; employee;

SELECT COUNT(column) FROM SELECT COUNT(*) FROM


COUNT() Counts rows
table; employee;

Finds minimum SELECT MIN(column) FROM SELECT MIN(age) FROM


MIN()
value table; employee;

Finds maximum SELECT MAX(column) FROM SELECT MAX(salary) FROM


MAX()
value table; employee;

Calculates total SELECT SUM(column) FROM SELECT SUM(salary) FROM


SUM()
sum table; employee;

Group By Example:

SELECT department, AVG(salary)


FROM employee
GROUP BY department;

This calculates the average salary per department [6] [7] .

2. String Functions
String functions manipulate and analyze text data.

Function Description Syntax Example

Converts to SELECT LOWER('HELLO'); →


LOWER() LOWER(string)
lowercase hello

Converts to SELECT UPPER('hello'); →


UPPER() UPPER(string)
uppercase HELLO

Returns string
LENGTH() LENGTH(string) SELECT LENGTH('hello'); → 5
length

Concatenates CONCAT(str1, str2, SELECT CONCAT('Hello',


CONCAT()
strings ...) 'World'); → HelloWorld
Function Description Syntax Example

Extracts SUBSTRING(str FROM SELECT SUBSTRING('abcdef'


SUBSTRING()
substring start FOR count) FROM 2 FOR 3); → bcd

SELECT TRIM(' hello '); →


TRIM() Removes spaces TRIM(string)
hello

Example:

SELECT LOWER(CONCAT('Hello', 'World')); -- Output: helloworld


SELECT LENGTH('PostgreSQL'); -- Output: 10

3. Date and Time Functions


These functions handle date and time values.

Function Description Syntax Example

CURRENT_DATE Current date CURRENT_DATE SELECT CURRENT_DATE;

NOW() Current timestamp NOW() SELECT NOW();

Difference AGE(timestamp1, SELECT AGE('2025-04-25',


AGE()
between dates timestamp2) '2000-01-01');

Extracts part of EXTRACT(field FROM SELECT EXTRACT(YEAR FROM


EXTRACT()
date/time source) CURRENT_DATE);

AGE Example:

SELECT AGE('2025-04-25', '2000-01-01'); -- Returns interval (years, months, days)

4. Conditional Functions
Conditional functions return values based on specific conditions.

CASE Expression

SELECT name,
CASE
WHEN salary &gt; 60000 THEN 'High'
ELSE 'Low'
END AS salary_level
FROM employee;

Returns 'High' if salary > 60000, else 'Low' [8] .


COALESCE()
Returns the first non-null value from a list.

SELECT COALESCE(middle_name, 'N/A') FROM employee;

If middle_name is NULL, returns 'N/A' [9] .

5. Window Functions
Window functions perform calculations across sets of rows related to the current row.

Function Description Syntax Example

SELECT name, ROW_NUMBER() OVER


Assigns unique ROW_NUMBER() OVER
ROW_NUMBER() (ORDER BY salary DESC) FROM
row number (ORDER BY column)
employee;

SELECT name, RANK() OVER


Assigns rank, RANK() OVER (ORDER
RANK() (ORDER BY salary DESC) FROM
gaps for ties BY column)
employee;

SELECT name, DENSE_RANK() OVER


Like RANK, no DENSE_RANK() OVER
DENSE_RANK() (ORDER BY salary DESC) FROM
gaps (ORDER BY column)
employee;

SUM(column) OVER SELECT id, SUM(amount) OVER


SUM() OVER Running total
(ORDER BY column) (ORDER BY id) FROM sales;

Example:

SELECT name, salary,


RANK() OVER (ORDER BY salary DESC) AS salary_rank
FROM employee;

6. Additional Useful Functions


NULLIF(expr1, expr2): Returns NULL if expr1 = expr2, else returns expr1.
GREATEST(val1, val2, ...): Returns the largest value.
LEAST(val1, val2, ...): Returns the smallest value.
Example:

SELECT NULLIF(10, 10); -- Returns NULL


SELECT GREATEST(1, 5, 3); -- Returns 5
SELECT LEAST(1, 5, 3); -- Returns 1
Summary Table
Category Example Function Syntax Example Description

Aggregate AVG() SELECT AVG(salary) FROM employee; Average value

String LOWER() SELECT LOWER('HELLO'); Lowercase text

Date/Time NOW() SELECT NOW(); Current timestamp

Conditional CASE See above Conditional logic

Window RANK() OVER See above Ranking rows

Tip: Practice these functions with your own tables to gain confidence and understanding.

PostgreSQL Equivalents and Examples for Common SQL Functions


Below are PostgreSQL equivalents, syntax, and examples for the functions you requested:
DATEADD, DATEPART, DATEDIFF, FORMAT, EOMONTH, LEAD, LAG, and PARTITION BY.

1. DATEADD
Purpose: Adds an interval to a date.
PostgreSQL Syntax:

SELECT date_column + INTERVAL '1 day' FROM table;


SELECT date_column + INTERVAL '2 month' FROM table;

Example:

SELECT CURRENT_DATE + INTERVAL '7 days' AS next_week;

2. DATEPART
Purpose: Extracts part of a date (year, month, day, etc.).
PostgreSQL Syntax:

SELECT EXTRACT(part FROM date_column) FROM table;

Example:
SELECT EXTRACT(YEAR FROM CURRENT_DATE) AS year;
SELECT EXTRACT(MONTH FROM '2025-04-25'::date) AS month;

3. DATEDIFF
Purpose: Calculates the difference between two dates.
PostgreSQL Syntax:

SELECT date1 - date2 AS difference; -- returns interval


SELECT EXTRACT(DAY FROM (date1 - date2)) AS days_diff;

Example:

SELECT '2025-04-25'::date - '2025-01-01'::date AS days_between; -- returns 114

4. FORMAT
Purpose: Formats values as strings.
PostgreSQL Syntax:

SELECT TO_CHAR(date_column, 'YYYY-MM-DD') FROM table;


SELECT TO_CHAR(numeric_column, 'FM999,999.00') FROM table;

Example:

SELECT TO_CHAR(NOW(), 'DD Mon YYYY') AS formatted_date;


SELECT TO_CHAR(12345.678, 'FM999,999.00') AS formatted_number;

5. EOMONTH (End of Month)


Purpose: Returns the last day of the month for a given date.
PostgreSQL Equivalent: Use date_trunc and interval arithmetic.
Syntax:

SELECT (date_trunc('month', date_column) + INTERVAL '1 month - 1 day')::date FROM table;

Example:
SELECT (date_trunc('month', '2025-04-25'::date) + INTERVAL '1 month - 1 day')::date AS en
-- Result: 2025-04-30

This is the standard workaround since PostgreSQL does not have a direct EOMONTH()
function [10] [11] [12] .

6. LEAD and LAG


Purpose: Accesses data from subsequent or previous rows in a result set.
Syntax:

SELECT value, LEAD(value) OVER (ORDER BY id) AS next_value FROM table;


SELECT value, LAG(value) OVER (ORDER BY id) AS prev_value FROM table;

Example:

SELECT id, salary,


LEAD(salary) OVER (ORDER BY id) AS next_salary,
LAG(salary) OVER (ORDER BY id) AS prev_salary
FROM employees;

7. PARTITION BY (with Window Functions)


Purpose: Divides result set into partitions to perform calculations.
Syntax:

SELECT department, salary,


RANK() OVER (PARTITION BY department ORDER BY salary DESC) AS dept_salary_rank
FROM employees;

Example:
This ranks employees within each department by salary.

Summary Table
PostgreSQL
Function Example
Equivalent

DATEADD date + INTERVAL SELECT CURRENT_DATE + INTERVAL '1 day';

DATEPART EXTRACT() SELECT EXTRACT(MONTH FROM CURRENT_DATE);

DATEDIFF date1 - date2 SELECT '2025-04-25'::date - '2025-01-01'::date;


PostgreSQL
Function Example
Equivalent

FORMAT TO_CHAR() SELECT TO_CHAR(NOW(), 'YYYY-MM-DD');

date_trunc + SELECT (date_trunc('month', '2025-04-25'::date) +


EOMONTH
INTERVAL INTERVAL '1 month - 1 day')::date; [10] [12]

SELECT LEAD(salary) OVER (ORDER BY id) FROM


LEAD/LAG LEAD()/LAG() OVER
employees;

PARTITION OVER (PARTITION SELECT RANK() OVER (PARTITION BY department ORDER BY


BY BY ...) salary DESC) FROM employees;

Note:
PostgreSQL does not have direct equivalents for some SQL Server functions, but the above
workarounds are standard and widely used.
For more details, refer to the [official PostgreSQL date/time functions documentation] [11] .

1. https://neon.tech/postgresql/postgresql-getting-started
2. https://www.datacamp.com/tutorial/beginners-introduction-postgresql
3. https://www.geeksforgeeks.org/postgresql-tutorial/
4. https://www.tutorialspoint.com/postgresql/index.htm
5. https://www.w3schools.com/postgresql/
6. https://neon.tech/postgresql/postgresql-aggregate-functions
7. https://www.slingacademy.com/article/postgresql-aggregation-sum-avg-min-max/
8. https://www.commandprompt.com/education/postgresql-conditional-expressions-explained-with-exam
ples/
9. https://neon.tech/postgresql/postgresql-tutorial/postgresql-coalesce
10. https://stackoverflow.com/questions/47785320/eomonth-equivalent-in-postgresql
11. https://www.postgresql.org/docs/current/functions-datetime.html
12. https://www.sherloqdata.io/sql-functions/eomonth-in-sql
PostgreSQL Advanced SQL Notes

Window Functions

Window functions perform calculations across sets of rows related to the current row, without collapsing rows like
aggregate functions do. They require the OVER clause and can include PARTITION BY, ORDER BY, and a frame clause.

Syntax:

SELECT column, window_function(args) OVER (


[PARTITION BY col1, col2]
[ORDER BY col3]
[ROWS BETWEEN ...]
) AS alias
FROM table;

• PARTITION BY: Divides data into groups (windows).

• ORDER BY: Orders rows within each partition.

• Frame clause: Limits the rows within the partition for the function.

Common Window Functions (with usage):

Function Description Example Usage

ROW_NUMBER() Row number within ROW_NUMBER() OVER (PARTITION BY dept ORDER BY salary
partition DESC)

RANK() Rank with gaps within RANK() OVER (ORDER BY score DESC)
partition

DENSE_RANK() Rank without gaps DENSE_RANK() OVER (ORDER BY score DESC)

SUM() Running total SUM(sales) OVER (PARTITION BY branch ORDER BY


sale_time)

AVG() Running average AVG(salary) OVER (PARTITION BY dept)

LAG(column, n) Value n rows before LAG(sales, 1) OVER (ORDER BY date)

LEAD(column, Value n rows after LEAD(sales, 1) OVER (ORDER BY date)


n)

NTILE(n) Divides partition into n NTILE(4) OVER (ORDER BY score)


buckets

FIRST_VALUE() Value from first row in FIRST_VALUE(salary) OVER (PARTITION BY dept ORDER BY
window salary)
LAST_VALUE() Value from last row in LAST_VALUE(salary) OVER (PARTITION BY dept ORDER BY
window salary)

NTH_VALUE() Value from nth row in NTH_VALUE(salary, 2) OVER (ORDER BY salary)


window

PERCENT_RANK() Percentage rank PERCENT_RANK() OVER (ORDER BY score)

CUME_DIST() Cumulative distribution CUME_DIST() OVER (ORDER BY score) [1][2][3]

Example Usage:

-- Running total of sales per branch ordered by sale_time


SELECT sale_time, branch,
SUM(total) OVER (PARTITION BY branch ORDER BY sale_time) AS running_total
FROM sales_data;

-- Row number within each department ordered by salary


SELECT emp_id, depname, salary,
ROW_NUMBER() OVER (PARTITION BY depname ORDER BY salary DESC) AS rn
FROM empsalary;

Types of Window Functions

• Aggregate Window Functions: SUM(), AVG(), COUNT(), MIN(), MAX()

• Ranking Functions: ROW_NUMBER(), RANK(), DENSE_RANK(), NTILE()

• Value Functions: LAG(), LEAD(), FIRST_VALUE(), LAST_VALUE(), NTH_VALUE()

• Distribution Functions: CUME_DIST(), PERCENT_RANK()[1][3][2]

Subqueries

A subquery is a query nested inside another SQL query.

Types of Subqueries in PostgreSQL

PostgreSQL supports several types of subqueries, each with its own syntax, example, and usage scenario:

1. Scalar Subquery

• Definition: Returns a single value (one row, one column).

• Syntax:
SELECT column1
FROM table1
WHERE column2 = (SELECT column3 FROM table2 WHERE condition);

• Example:

SELECT first_name, last_name, salary


FROM employees
WHERE salary > (SELECT max(salary) FROM employees WHERE first_name = 'Alexander');

• Usage: Used when you need to compare a value in the outer query to a single value returned by the subquery
(e.g., maximum, minimum, or specific value lookup)[1][2].

2. Multi-row Subquery

• Definition: Returns multiple rows (one column, multiple rows).

• Syntax:

SELECT column1
FROM table1
WHERE column2 IN (SELECT column3 FROM table2 WHERE condition);

• Example:

SELECT * FROM COMPANY WHERE ID IN (SELECT ID FROM COMPANY WHERE SALARY > 45000);

• Usage: Used with operators like IN, ANY, SOME, or ALL to compare a value to a set of values returned by the
subquery[1][3][4].

3. Row Subquery

• Definition: Returns a single row with multiple columns.

• Syntax:

SELECT column1
FROM table1
WHERE (column2, column3) = (SELECT column4, column5 FROM table2 WHERE condition);
• Example:

SELECT first_name
FROM employees
WHERE ROW(department_id, manager_id) = (
SELECT department_id, manager_id
FROM departments
WHERE location_id = 1800
);

• Usage: Used when you need to compare multiple columns at once between tables[2].

4. Correlated Subquery

• Definition: References columns from the outer query; executed once for each row processed by the outer query.

• Syntax:

SELECT column1
FROM table1 t1
WHERE column2 = (
SELECT MAX(column3)
FROM table2 t2
WHERE t2.column4 = t1.column4
);

• Example:

SELECT name
FROM employees e1
WHERE salary = (
SELECT MAX(salary)
FROM employees e2
WHERE e2.department_id = e1.department_id
);

• Usage: Useful for queries where the subquery’s result depends on the current row of the outer query[1].

5. Subquery in the FROM Clause (Derived Table)


• Definition: The subquery acts as a temporary table used by the outer query.

• Syntax:

SELECT alias.*
FROM (SELECT column1, column2 FROM table1 WHERE condition) AS alias
WHERE alias.column1 > value;

• Example:

SELECT sc1, sc2, sc3


FROM (SELECT c1 AS sc1, c2 AS sc2, c3*3 AS sc3 FROM tb1) AS sb
WHERE sc1 > 1;

• Usage: Useful for performing calculations or filtering on intermediate results[2].

General Subquery Guidelines

• Subqueries must be enclosed in parentheses.

• Scalar subqueries must return only one row and one column; otherwise, an error occurs.

• Multi-row subqueries should be used with operators that accept multiple values (IN, ANY, etc.).

• Subqueries can be used in SELECT, INSERT, UPDATE, and DELETE statements[4].

• Subqueries cannot use ORDER BY unless combined with LIMIT/OFFSET or used in the outer query[4].

Summary Table

Type Returns Common Usage Example Typical


Operator

Scalar 1 row, 1 column WHERE column = (SELECT MAX(column) FROM ...) =, <, >, <=, >=

Multi-row Multiple rows, 1 WHERE column IN (SELECT column FROM ...) IN, ANY,
column SOME, ALL

Row 1 row, multiple WHERE (col1, col2) = (SELECT col3, col4 FROM ...) =
columns

Correlated Varies WHERE column = (SELECT MAX(column) FROM ... =, <, >, etc.
WHERE ... = outer_table.column)
FROM Clause Table-like SELECT * FROM (SELECT ... FROM ...) AS alias WHERE N/A
(Derived) ...

These subquery types allow you to write flexible and powerful SQL statements in PostgreSQL[1][3][2][4].

Types of Subqueries by clause:

• WHERE Subquery: Used in the WHERE clause.

SELECT name FROM employees WHERE department_id = (SELECT id FROM departments WHERE name = 'HR');

• IN Subquery: Checks if a value matches any value in a list.

SELECT name FROM employees WHERE department_id IN (SELECT id FROM departments WHERE location =
'NY');

• EXISTS Subquery: Returns true if the subquery returns any rows.

SELECT name FROM employees WHERE EXISTS (SELECT 1 FROM salaries WHERE employees.id =
salaries.emp_id AND amount > 100000);

Common Table Expressions (CTE)

A CTE provides a temporary result set that can be referenced within a SELECT, INSERT, UPDATE, or DELETE statement.

Syntax:

WITH cte_name AS (
SELECT ...
)
SELECT * FROM cte_name;

• Simplifies complex joins or subqueries.

• Can be referenced multiple times in the main query.

Example:

WITH high_earners AS (
SELECT id, salary FROM employees WHERE salary > 100000
)
SELECT * FROM high_earners;
Recursive CTE

A recursive CTE references itself, useful for hierarchical or tree-structured data.

Syntax:

WITH RECURSIVE cte_name AS (


SELECT ... -- anchor member / base query
UNION ALL
SELECT ... FROM cte_name WHERE ... -- recursive member / recursive query
)
SELECT * FROM cte_name;

Example: Factorial Calculation

WITH RECURSIVE factorial_cte(n, factorial) AS (


SELECT 1, 1
UNION ALL
SELECT n + 1, (n + 1) * factorial FROM factorial_cte WHERE n < 5
)
SELECT * FROM factorial_cte;

Example: Hierarchical Data

WITH RECURSIVE org_chart AS (


SELECT id, name, manager_id FROM employees WHERE manager_id IS NULL
UNION ALL
SELECT e.id, e.name, e.manager_id FROM employees e
JOIN org_chart o ON e.manager_id = o.id
)
SELECT * FROM org_chart;

HAVING Clause

The HAVING clause is used to filter groups after aggregation, unlike WHERE which filters rows before aggregation.

Syntax:

SELECT department, COUNT(*) FROM employees


GROUP BY department
HAVING COUNT(*) > 5;

• Use HAVING with aggregate functions (e.g., SUM(), COUNT()).


PostgreSQL Procedures

Procedures are routines that can perform operations such as inserts, updates, and control transactions. They can accept
parameters, have output variables, and be called with or without arguments.

Basic Procedure Syntax:

CREATE PROCEDURE procedure_name([parameters])


LANGUAGE plpgsql
AS $$
BEGIN
-- statements
END;
$$;

Procedure with Parameters:

CREATE PROCEDURE raise_salary(emp_id INT, increment NUMERIC)


LANGUAGE plpgsql
AS $$
BEGIN
UPDATE employees SET salary = salary + increment WHERE id = emp_id;
END;
$$;

Procedure with Output Variable:

CREATE PROCEDURE get_salary(emp_id INT, OUT emp_salary NUMERIC)


LANGUAGE plpgsql
AS $$
BEGIN
SELECT salary INTO emp_salary FROM employees WHERE id = emp_id;
END;
$$;

Calling a Procedure with Output Variable:

CALL get_salary(101, emp_salary);


-- emp_salary will hold the output value

Modifying (ALTER) a Procedure:

ALTER PROCEDURE procedure_name(args) RENAME TO new_procedure_name;

Encryption:
• PostgreSQL does not natively support procedure encryption. You can restrict access using roles and permissions.

Stored Procedures vs. Functions

Feature Procedure Function

Returns value No (can use OUT parameters) Yes (must return a value)

Call syntax CALL procedure_name(...) SELECT function_name(...)

Transaction Can manage transactions (BEGIN/COMMIT) Cannot manage transactions

Use in queries No Yes

Stored Procedure Example in Detail

-- Create a procedure to transfer funds between accounts


CREATE PROCEDURE transfer_funds(
from_account INT,
to_account INT,
amount NUMERIC
)
LANGUAGE plpgsql
AS $$
BEGIN
UPDATE accounts SET balance = balance - amount WHERE account_id = from_account;
UPDATE accounts SET balance = balance + amount WHERE account_id = to_account;
COMMIT;
END;
$$;

-- Call the procedure


CALL transfer_funds(1001, 1002, 500);

These notes cover advanced SQL features in PostgreSQL, including window functions, subqueries, CTEs (including
recursive), the HAVING clause, and stored procedures with examples and usage details.[1][2][3][4][5]

1. https://neon.tech/postgresql/postgresql-window-function

2. https://www.postgresql.org/docs/current/functions-window.html

3. https://www.timescale.com/learn/postgresql-window-functions
4. https://www.draxlr.com/blogs/common-table-expressions-and-its-example-in-postgresql/

5. https://www.stratascratch.com/blog/learn-to-use-a-recursive-cte-in-sql-query/

You might also like