0% found this document useful (0 votes)
16 views47 pages

SQL

Uploaded by

aditya
Copyright
© © All Rights Reserved
Available Formats
Download as PDF, TXT or read online on Scribd
Download as pdf or txt
0% found this document useful (0 votes)
16 views47 pages

SQL

Uploaded by

aditya
Copyright
© © All Rights Reserved
Available Formats
Download as PDF, TXT or read online on Scribd
Download as pdf or txt
Download as pdf or txt
You are on page 1/ 47

🛋️

SQL
Introduction

Types of data

Structured Data: Oracle, MySQL, Mircrosoft SQL server, PostgreSQL, Access

Unstructured Data (NoSQL - Not only SQL): Eg. Audios, images, Cassandra, Hbase (Hives), Hadoops, Maria DB,
Mongo DB.
Semi-structured Data: Combination of structured and unstructured data. Eg. Wikipedia

Types of Databases

Relational Database (RDBMS) Non-relational (NoSQL)

Data stored in tables Data not stored in tables

MySQL, oracle, PostgreSQL MongoDB

Introduction to SQL

It is the language that is used to communicate with data that is stored in relational database

Everything we do online generates data, and this data needs to be stored in order to analyze it in future

Every data has a type and it is called as datatype. There are different types of datatypes in SQL that can be
utilized in order to store various forms of data.

It is used to perform CRUD operations:

Create

Read

Update

Delete

Structured data

When the data is stored in rows and columns and stored in tables, it’s called structured data. And to talk to
structured data, we have SQL

When we put these type of multiple tables together, it’s called a database.

Collection of tables is called as database, and to manage we need a system, that is called as database
management system.

Rows+column-->Tables-->Multiple tables-->Database

Role of a database

Users request the information from the database.

Server has the capability to take the request from DB

Server has no capability to store the data, but it has some storage to store the codes or programs

DB gives the response to the server based on the user request

SQL 1
Statements

Making a default schema

USE database_name;

Creating and dropping a database

Syntax for creating

CREATE DATABASE db_name;

Syntax for deleting

DROP DATABASE db_name;

Dropping a table

DROP TABLE db_name;

DROP and TRUNCATE command


DROP completely deletes the table WHILE
TRUNCATE deletes the table values, not the table itself

DROP TABLE table_name;

TRUNCATE TABLE table_name;

UPDATE statement

1. The UPDATE statement in MySQL is used to modify existing records in a table.

2. You can update one or more columns for all rows or specific rows that match a certain condition.

3. If no condition is specified with WHERE clause then it will update for the whole table that’s why it’s important
to mention the WHERE clause and its condition

Syntax

UPDATE table_name
SET column1_name = value1, column2_name = value2,...
WHERE condition;

Eg

SQL 2
UPDATE employee_demographics
SET first_name = "Leslie", last_name = "Knope"
WHERE employee_id = 1

UPDATE employee_salary
SET salary = "40000"
WHERE employee_id IN (1,2);

DELETE statement

1. The DELETE statement in SQL is used to remove rows from a table. It can be used with or without a WHERE

clause.

2. If a WHERE clause is not specified, all rows in the table will be deleted, which can be dangerous and is
generally not recommended unless you intend to clear the entire table.

Syntax

DELETE FROM table_name


WHERE condition;

Eg

DELETE FROM parks_and_recreation.employee_demographics


WHERE employee_id = 12

INDEX

An index in SQL is a data structure that improves the speed of data retrieval operations. Think of it like a table
of contents in a book — it helps quickly locate the data you're looking for, without having to scan the entire
table.

Syntax

For creating index

CREATE INDEX index_name


ON table_name (column1, column2, column3,...);

For deleting index

DROP INDEX index_name


ON table_name;

For showing index

SHOW INDEX FROM table_name;

Guidelines of Index

Automatically creates the indexes for PRIMARY KEY and UNIQUE columns

Index columns that you frequently use to retrieve the data

Index columns that are used for joins to improve join performance

Avoid columns that contain too many null values

Small tables don’t require indexes

VIEW command

SQL 3
A view is a virtual table in SQL that represents the result of a stored query. It does not store data physically;
instead, it stores the SQL query used to generate the data when needed. Views can be used to simplify
complex queries, restrict access to certain columns or rows, and abstract data complexity.

Why Use Views?


1. Simplify Complex Queries: You can create a view for a complex query and then use that view like a table,
making the query easier to manage.

2. Security: Views allow you to restrict access to specific data. For example, you can create a view that only
exposes certain columns, hiding sensitive data.

3. Data Abstraction: You can abstract complex logic by storing it in a view, so users don’t have to write
complicated SQL each time.

4. Reusability: Once a view is created, it can be reused in different parts of your application or by different
users.

CREATE VIEW view_name


AS
SELECT columns
FROM student AS st
INNER JOIN city AS ci
ON st.city = ci.cid;

OR

CREATE OR REPLACE VIEW view_name


AS
SELECT columns
FROM student AS st
INNER JOIN city AS ci
ON st.city = ci.cid;

SELECT*
FROM view_name

CHANGING THE VIEW NAME

RENAME TABLE old_view_name


TO new_view_name;

SELECT*
FROM new_view_name;

DELETING THE VIEW

DROP VIEW view_name

ALTER command
The ALTER command in SQL is used to modify the structure of an existing table. It allows you to add, modify, or
drop columns, constraints, and other table attributes.

Add a new column

SQL 4
ALTER TABLE table_name
ADD COLUMN column_name column_definition;

Example:

ALTER TABLE employees


ADD COLUMN phone_number VARCHAR(15);

Modify a Column
Change the definition of an existing column (e.g., data type, size).

ALTER TABLE table_name


MODIFY column_name new_definition;

Example:

ALTER TABLE employees


MODIFY COLUMN phone_number VARCHAR(20);

Rename a column

Rename a column in the table (not supported in some databases).

ALTER TABLE table_name


RENAME COLUMN old_column_name TO new_column_name;

Example:

ALTER TABLE employees


RENAME COLUMN phone_number TO contact_number;

Drop a column
Remove an existing column from the table.

ALTER TABLE table_name


DROP COLUMN column_name;

Example:

ALTER TABLE employees


DROP COLUMN contact_number;

Rename the table


Rename the entire table.

ALTER TABLE old_table_name


RENAME TO new_table_name;

Example:

ALTER TABLE employees


RENAME TO staff;

Add a constraint
Add a constraint like a primary key, unique constraint, or foreign key.

Primary Key:

SQL 5
ALTER TABLE table_name
ADD CONSTRAINT constraint_name PRIMARY KEY (column_name);

Example:

ALTER TABLE employees


ADD CONSTRAINT pk_employee_id PRIMARY KEY (id);

Foreign Key:

ALTER TABLE table_name


ADD CONSTRAINT constraint_name FOREIGN KEY (column_name) REFERENCES other_table(c
olumn_name);

Example:

ALTER TABLE employees


ADD CONSTRAINT fk_department FOREIGN KEY (department_id) REFERENCES departments(d
epartment_id);

Drop a constraint

Remove an existing constraint.

ALTER TABLE table_name


DROP CONSTRAINT constraint_name;

Example:

ALTER TABLE employees


DROP CONSTRAINT pk_employee_id;

COMMIT AND ROLLBACK

1. A ROLLBACK statement in SQL is used to undo transactions that have not yet been saved to the database. It
reverts the database back to the state it was in before the transaction began.

2. COMMIT: Saves the changes made during the transaction to the database. Once this is pressed, the data
can’t be rolled back i.e. the change is permanent

Transactions
The purpose and meaning of transactions in MySQL (or any database) revolve around ensuring data
consistency, integrity, and reliability in cases where multiple operations need to be treated as a single unit.
Let's break it down:

What is a Transaction?
A transaction is a sequence of one or more SQL operations that are executed as a single unit. It follows the
ACID properties to ensure the data remains consistent and reliable, even in the event of errors, crashes, or
other unexpected issues.

Why Use Transactions?


1. Atomicity:

All or Nothing: Either all operations in a transaction are successfully completed, or none of them are
applied. For example, if you’re transferring money from one bank account to another, both the debit and
credit operations must succeed together.

2. Consistency:

SQL 6
Ensures the database moves from one valid state to another. If the transaction fails, the database is
"rolled back" to its state before the transaction started.

3. Isolation:

Transactions operate independently of one another. If multiple users are working on the same database,
each transaction remains isolated until it’s completed.

4. Durability:

Once a transaction is committed, the changes are permanent, even in case of system failure.

Example to Understand the Point

Without Transactions:
Imagine a banking application that transfers ₹500 from Account A to Account B using two operations:

1. Deduct ₹500 from Account A.

2. Add ₹500 to Account B.

If the first operation succeeds but the second one fails (e.g., due to a network issue), your database will now
have inconsistent data:

Account A lost ₹500.

Account B didn’t gain ₹500.

With Transactions:
The same operations are wrapped in a transaction:

1. Start the transaction.

2. Deduct ₹500 from Account A.

3. Add ₹500 to Account B.

4. Commit the transaction if both operations succeed.

5. Rollback if any operation fails (undo all changes).

This ensures either:

Both accounts are updated, or

No changes are made, maintaining consistency.

Creating a SQL table

Syntax

CREATE TABLE table_name (


column 1 datatype,
column 2 datatype,
column 3 datatype,

);

Three types of category in datatypes

String

S. No Datatypes Size

1 CHAR(size) 0 to 255

2 VARCHAR(size) 0 to 65535

3 BINARY(size) 0 to 255

4 VARBINARY(size) 0 to 65535

5 TINYTEXT 255 characters

SQL 7
6 TEXT(size) 65,535 bytes

7 MEDIUMTEXT 16,777,215 characters

8 LONGTEXT 4,294,967,295 characters

9 TINYBLOB 255 bytes

10 BLOB(size) 65,535 bytes

11 MEDIUMBLOB 16,777,215 bytes

12 LONGBLOB 4,294,967,295 bytes

13 ENUM(val1, val2, val3, …) list up to 65535 values

14 SET(val1, val2, val3, …) list up to 64 values

Numeric

S. No Datatypes Size Points to remember

1 BIT(size) 1 to 64

2 TINYINT(size) -128 to 127

3 INT(size) -2147483648 to 2147483647

4 INTEGER(size) -2147483648 to 2147483647

5 SMALLINT(size) -32768 to 32767

6 MEDIUMINT(size) -8388608 to 8388607

-9223372036854775808 to
7 BIGINT(size)
9223372036854775807

8 BOOL 0 or 1

9 BOOLEAN 0 or 1

10 FLOAT(p)

size = value before period; d = value after


11 DOUBLE(size, d) 255.568
period

Same as double, but the value of size and


12 DECIMAL(size, d)
d is fixed with size = 60 and d = 30.

13 DEC(size, d) Short form of decimal datatype

Date and Time

S. No Datatypes Size Points to remember

‘1000-01-01’ to ‘9999-12-
1 DATE Year-month-date
31’

2 DATETIME(fsp) YYYY-MM-DD hh:mm:ss

Same format as DATETIME(fsp) but used for older


3 TIMESTAMP
dating

4 TIME(fsp) hh:mm:ss

5 YEAR four-digit format : 1901

Eg

CREATE TABLE product(


pid INT,
pname VARCHAR(50),
pcompany VARCHAR(50),
price INT
);

How to insert data in tables with SQL

Syntax

SQL 8
INSERT INTO table_name (column1, column2, ...)
VALUES (value1, value2)

Eg

INSERT INTO product(pid, pname, pcompany, price)


VALUES ("1", "Ram Kumar", "Verizon", "34");

Syntax

INSERT INTO table_name (column1, column2....)


VALUES
(value 1, value 2....),
(value 1, value 2....);

List of constraints in MySQL

1. NOT NULL - Entry is necessary, can’t be left unfilled

2. UNIQUE - This keyword can be used where there will always be unique identity such as phone number and ID

3. DEFAULT - If you don’t fill it, it should get filled by default like city name.

4. CHECK - Can be used to put condition. The block can only be filled when the conditions would be fulfilled

5. PRIMARY KEY - Always has unique data and can’t have a null value. A table can have only one primary key
constraint such as id can be set as primary key because it’s always unique and doesn’t have null value but
name can’t be because names can be same.

6. FOREIGN KEY - Key used to link two tables together. Foreign key in one table is used to point primary key in
another table

Syntax with eg

CREATE TABLE table_name(


id INT NOT NULL UNIQUE,
name VARCHAR (50) NOT NULL UNIQUE,
age INT NOT NULL CHECK (age=18),
gender VARCHAR (10) NOT NULL,
phone VARCHAR (10) NOT NULL UNIQUE,
city VARCHAR (10) NOT NULL DEFAULT 'Agra'
);

INSERT INTO table_name (id, name, age, gender, phone, city)


VALUES
("1", "aditya", "22", "Male", "9929936956", "Bhilwara");

For default city, this will be the code

INSERT INTO table_name (id, name, age, gender, phone)


VALUES
("1", "aditya", "22", "Male", "9929936956");

Usage of primary key

CREATE TABLE personal(


id INT NOT NULL AUTO_INCREMENT,
name VARCHAR (50) NOT NULL,
age INT NOT NULL,
city VARCHAR (10) NOT NULL,

SQL 9
PRIMARY KEY (id)
);

ALTER TABLE table_name


ADD PRIMARY KEY (id);

Usage of foreign key

CREATE TABLE city(


cid INT NOT NULL AUTO_INCREMENT,
cityname VARCHAR (10) NOT NULL,
PRIMARY KEY (cid)
);

INSERT INTO city (cityname)


VALUES
('Agra'),
('Delhi'),
('Bhopal'),
('Jaipur'),
('Noida');

CREATE TABLE personal(


id INT NOT NULL,
name VARCHAR (50) NOT NULL,
age INT NOT NULL,
gender VARCHAR (10) NOT NULL,
phone VARCHAR (10) NOT NULL,
city INT NOT NULL,
PRIMARY KEY (id),
FOREIGN KEY (city) REFERENCES city (cid)
);

INSERT INTO personal (id, name, age, gender, phone, city)


VALUES
(1, "aditya", 22, "F", "9929936956", 1),
(2, "Mohit", 23, "F", "9929936956", 2),
(3, "Shaurya", 24, "M", "9929936956", 3),
(4, "Sarthak", 25, "M", "9929936956", 4),
(5, "Ram", 26, "M", "9929936956", 5);

WHERE clause syntax

Syntax

SELECT column1, column2, column3


FROM table_name
WHERE condition;

Eg.

SELECT id, name, age, number, city


FROM personal
WHERE age>22;

SQL 10
SELECT*
FROM employee_demographics
WHERE gender = "Female";

SELECT first_name, last_name, gender


FROM employee_demographics
WHERE gender != 'Female'

WHERE comparison operators

Operator Description

= Equal

> Greater than

< Less than

≥ Greater than or equal to

≤ Less than or equal

<> Or ≠ Not equal

BETWEEN Between a certain range

LIKE Search for a pattern

IN To specify multiple possible values for a column

Operators Syntax and example

AND operator
If we have to imply multiple conditions then we can utilize these operators .

SELECT column1, column2, column3,...


FROM table_name
WHERE condition1 AND CONDITION2 AND CONDITION3

SELECT first_name, last_name, gender, age


FROM employee_demographics
WHERE gender != 'Female' AND age>21

OR operator

SELECT column1, column2, column3,...


FROM table_name
WHERE condition1 OR CONDITION2 OR CONDITION3

SELECT first_name, last_name, gender, age


FROM employee_demographics
WHERE gender != 'Female' OR age>21

IN operator
IN operator - Tells exactly those values that are entered in this operator

SELECT column1, column2, column3,...


FROM table_name
WHERE column_name IN (value1, value2, ...);

SELECT first_name, last_name, gender, age


FROM employee_demographics

SQL 11
WHERE age IN (36,44)

NOT operator

SELECT column1, column2, column3,...


FROM table_name
WHERE column_name NOT (value1, value2, ...);

NOT operator - Used when we have to make the results opposite

SELECT first_name, last_name, gender, age


FROM employee_demographics
WHERE NOT gender = 'Female' OR age<=21

NOT IN operator

SELECT column1, column2, column3,...


FROM table_name
WHERE column_name NOT IN (value1, value2, ...);

NOT IN operator - Gives all the value that are not mentioned

SELECT first_name, last_name, gender, age


FROM employee_demographics
WHERE age NOT IN (36,44)

BETWEEN AND operator

SELECT column1, column2, column3,...


FROM table_name
WHERE column_name BETWEEN value1 AND value2

SELECT first_name, last_name, gender, age


FROM employee_demographics
WHERE age BETWEEN 36 AND 44

NOT BETWEEN AND operator

SELECT column1, column2, column3,...


FROM table_name
WHERE column_name NOT BETWEEN value1 AND value2

SELECT first_name, last_name, gender, age


FROM employee_demographics
WHERE age NOT BETWEEN 36 AND 44

LIKE operator
LIKE operator can be used to perform pattern matching in SQL queries.

LIKE operator with Wildcard characters

% percentage sign - Represents zero, one or multiple characters

SQL 12
_ underscore sign - Represents a single character

Pattern Description

LIKE ‘a%’ Starts with “a”

LIKE ‘%a’ Ends with “a”

LIKE ‘%am%’ Have “am” in any position

Starts with “a” and ends with


LIKE ‘a%m’
“m”

LIKE ‘_a%’ “a” in the second position

LIKE ‘__a%’ “a” in the third position

Can be used the same way


NOT LIKE
like this

Syntax

SELECT *
FROM table_name
WHERE column_name LIKE pattern;

SELECT *
FROM table_name
WHERE column_name NOT LIKE pattern;

Making the syntax case-sensitive

You can simply add the word BINARY

SELECT first_name, last_name


FROM employee_demographics
WHERE BINARY first_name LIKE "A%";

Using LIKE operator with OR and AND operator


This type of operator can be combined with OR and AND operator as well

SELECT first_name, last_name


FROM employee_demographics
WHERE first_name LIKE "a%" OR first_name LIKE "%pr%";

April Ludgate

Ann Perkins

Andy Dwyer

This will be the output, it will be either the names starting with A or that has pr within it or it can be both as
in case of April

NULL Operator

IS NULL AND NOT NULL operator

In MySQL, the IS NULL and IS NOT NULL operators are used to check whether a column's value is NULL or not.

SELECT column1, column2...


FROM table_name
WHERE column IS NULL;

SQL 13
SELECT column1, column2...
FROM table_name
WHERE column IS NOT NULL;

SELECT age
FROM employee_demographics
WHERE age IS NOT NULL;

Regular Expression
Regular expressions can be used for pattern matching in SQL queries. The function REGEXP (or RLIKE , which is a
synonym) is used to match a string against a regular expression pattern.

Syntax

SELECT column_name
FROM table_name
WHERE column_name REGEXP 'pattern';

Regular expression pattern with description

Pattern with an
Sign Description
eg

^ ‘^ra’ Beginning of string

$ ‘an$’ End of string

Any character listed between the square brackets. That is the word should have either r
or m or s as given in the eg. 1. Also it can be used as ‘[rm]s’. It will search as rs and ms.
[…] ‘[rms]’
2. If it’s sth like this ‘^[rs]’, it will search for words that either start with r or with s. 3. If it’s
sth like this ‘[rs]$’. it will search for words that either ends with r or with s

[a-z] ‘[a-h]e’ Match with in the range like ae, be, ce, de, …. he

Matches any of the patterns p1, p2, and p3. This can be used with ^, $ sign as well for
p1|p2|p3 ‘tom|dick|harry’
finding the first and last name specifically

ORDER BY
It can be used to keep things in order either in ascending order or descending order. Even multiple things can be
kept in order. But the priority will be the first object

Syntax

SELECT column1, column2, column3,...


FROM table_name
ORDER BY column1, column2, ... ASC|DESC;

Eg

SELECT *
FROM employee_demographics
ORDER BY first_name DESC ;

With WHERE clause

SELECT *
FROM employee_demographics
WHERE age > 20
ORDER BY first_name DESC ;

DISTINCT

SQL 14
The DISTINCT keyword in MySQL is used to remove duplicate rows from the result set.

SELECT DISTINCT column1, column2...


FROM table_name;

SELECT DISTINCT age


FROM employee_demographics
ORDER by age;

LIMIT AND OFFSET


The LIMIT operator in MySQL is used to specify the number of records to return from a query.

Syntax

SELECT column1, column2..


FROM table_name
WHERE condition (optional)
ORDER BY column1, column2 (optional)
LIMIT number;

Eg

SELECT age
FROM employee_demographics
ORDER BY age
LIMIT 3

SELECT*
FROM employee_demographics
WHERE gender = "Female"
ORDER BY age
LIMIT 4

SELECT*
FROM employee_demographics
ORDER BY age
LIMIT 3, 3

Aggregate functions

1. The COUNT function returns the number of rows that match a specified condition.

2. The SUM function returns the total sum of a numeric column.

3. The AVG function returns the average value of a numeric column.

4. The MIN function returns the smallest value in a specified column.

5. The MAX function returns the largest value in a specified column.

Syntax

SELECT COUNT (column_name), SUM (column_name), AVG (column_name), MIN (column_name), MA


FROM table_name
WHERE condition;

Eg

SQL 15
SELECT COUNT(DISTINCT gender) AS Gender
FROM employee_demographics

JOINS

Inner Join

An inner join in SQL is used to combine rows from two or more tables based on a related column between them.

SELECT columns
FROM table1
INNER JOIN table2
ON table1.column = table2.column;

SELECT*
FROM personal AS p
INNER JOIN city AS c
ON p.city = c.cid;

SELECT p.id, p.name, c.cityname


FROM personal AS p
INNER JOIN city AS c
ON p.city = c.cid;

SELECT p.id, p.name, c.cityname


FROM personal AS p
INNER JOIN city AS c
ON p.city = c.cid
WHERE c.cityname = "Agra";
ORDER BY p.name

Outer Join

Left Join

A left outer join returns all rows from the left table ( table1 ), and the matched rows from the right table
( table2 ). If there is no match, NULL values are returned for the columns from table2 .

Syntax

SELECT columns
FROM table1
LEFT JOIN table2
ON table1.column = table2.column;

Eg

SELECT dem.employee_id, dem.first_name, dem.last_name, sal.employee_id, sal.first


FROM employee_demographics AS dem
LEFT JOIN employee_salary AS sal
ON dem.employee_id = sal.employee_id;

employee_id first_name last_name employee_id first_name last_name

1 Leslie Knope 1 Leslie Knope

3 Tom Haverford 3 Tom Haverford

4 April Ludgate 4 April Ludgate

5 Jerry Gergich 5 Jerry Gergich

SQL 16
6 Donna Meagle 6 Donna Meagle

7 Ann Perkins 7 Ann Perkins

8 Chris Traeger 8 Chris Traeger

9 Ben Wyatt 9 Ben Wyatt

10 Andy Dwyer 10 Andy Dwyer

11 Mark Brendanawicz 11 Mark Brendanawicz

12 Craig Middlebrooks 12 Craig Middlebrooks

Right Join
A RIGHT JOIN , is a type of join operation in SQL that returns all rows from the right-hand table ( table2 ), and
the matched rows from the left-hand table ( table1 ). If there is no match, NULL values are returned for the
columns from table1 .

Syntax

SELECT columns
FROM table1
RIGHT JOIN table2
ON table1.column = table2.column;

Eg

SELECT dem.employee_id, dem.first_name, dem.last_name, sal.employee_id, sal.first


FROM employee_demographics AS dem
RIGHT JOIN employee_salary AS sal
ON dem.employee_id = sal.employee_id;

Employee_id first_name last_name employee_id first_name last_name

1 Leslie Knope 1 Leslie Knope

NULL NULL NULL 2 Ron Swanson

3 Tom Haverford 3 Tom Haverford

4 April Ludgate 4 April Ludgate

5 Jerry Gergich 5 Jerry Gergich

6 Donna Meagle 6 Donna Meagle

7 Ann Perkins 7 Ann Perkins

8 Chris Traeger 8 Chris Traeger

9 Ben Wyatt 9 Ben Wyatt

10 Andy Dwyer 10 Andy Dwyer

11 Mark Brendanawicz 11 Mark Brendanawicz

12 Craig Middlebrooks 12 Craig Middlebrooks

FULL JOIN (Works only in other sql’s, not in MySQL

SELECT column_names
FROM table1
FULL JOIN table2
ON table1.column_name = table2.column_name;

Cross Join

1. Join where each row from the first table is combined with every row from the second table. Essentially, it
produces a Cartesian product of the two tables involved in the join.

2. Returns cartesian product

3. Doesn’t require a join condition

SQL 17
4. It’s mostly useless only

SELECT columns
FROM table1
CROSS JOIN table2;

Joining Multiple Tables

CREATE TABLE Student_Table (


Id INT NOT NULL UNIQUE,
Name VARCHAR (50) NOT NULL,
Age INT NOT NULL,
Courses INT NOT NULL,
City INT NOT NULL
);

INSERT INTO Student_Table(Id, Name, Age, Courses, City)


VALUES
(1, "Ram Kumar", 19, 1, 1),
(2, "Salman Khan", 18, 3, 2),
(3, "Meera Khan", 19, 1, 1),
(4, "Sarita Kumari", 21, 2, 3)

CREATE TABLE City_Table (


Cid INT NOT NULL,
City VARCHAR (10) NOT NULL
);

INSERT INTO City_Table (Cid, City)


VALUES
(1, "Agra"),
(2, "Bhopal"),
(3, "Delhi"),
(4, "Noida");

CREATE TABLE Courses_Table (


Crid INT NOT NULL UNIQUE,
Course VARCHAR (10) NOT NULL UNIQUE
);

INSERT INTO Courses_Table (Crid, Course)


VALUES
(1, "Btech"),
(2, "BCA"),
(3, "BBA");

SELECT st.Id, st.Name, st.Age, ct.City, cota.Course


FROM Student_Table AS st
INNER JOIN City_Table AS ct
ON st.City = ct.Cid
INNER JOIN Courses_Table AS cota
ON st.Courses = cota.Crid
ORDER BY Id;

SQL 18
Id Name Age City Course

1 Ram Kumar 19 Agra Btech

2 Salman Khan 18 Bhopal BBA

3 Meera Khan 19 Agra Btech

4 Sarita Kumari 21 Delhi BCA

Natural Join

1. The NATURAL JOIN in SQL automatically joins two tables based on all columns with the same name and
compatible data types in both tables. It eliminates the need to explicitly specify the ON clause, as the join
condition is implicitly based on the shared column names. If there is any problem with the same type of
columns, it will automatically become cross join.

2. Just like CROSS JOIN this also doesn’t need any JOIN condition

SELECT column_names
FROM table1
NATURAL JOIN table2;

Self Join

A self join is a type of SQL join in which a table is joined with itself. It is useful when you need to compare
rows within the same table.

Often used for hierarchical or comparative data, such as finding relationships (e.g., employees and their
managers), duplicates, or specific patterns.

SELECT a.column1, b.column2


FROM table_name a
JOIN table_name b
ON a.some_column = b.some_column
WHERE some_condition;

GROUP BY

1. Used for grouping

2. This clause is used in conjunction with the SELECT statements and Aggregate functions to group rows together
by common column values.

3. If you want to use “WHERE” clause then you have to use it before GROUP BY clause

Syntax

SELECT columns
FROM table_name
WHERE condition (optional)
GROUP BY column_name;

SELECT columns
FROM table1 INNER JOIN table2
ON table1.column_name = table2.column_name
WHERE condition (optional)
GROUP BY column_name;

SQL 19
Eg

SELECT city, COUNT(city) AS frequency


FROM aditya.personal
GROUP BY city;

SELECT c.cityname, COUNT(p.city) AS "Frequency of cities"


FROM personal AS p
INNER JOIN city AS c
ON p.city = c.cid
GROUP BY city;

SELECT c.cityname, COUNT(p.city) AS Total


FROM personal AS p
INNER JOIN city AS c
ON p.city = c.cid
WHERE p.age>20
GROUP BY city
ORDER BY Total DESC;

Limitations
In SQL, when you use GROUP BY , you must either:

Include each non-aggregated column in the GROUP BY clause, or

Use an aggregate function (such as MAX , SUM , etc.) for the column.

SELECT emp_NAME, DEPT_NAME, MAX(SALARY) AS max_salary


FROM employee
GROUP BY DEPT_NAME;

This will throw an error since emp_NAME is not aggreagated or used in GROUP BY

HAVING clause

If you’ve to put some condition after GROUP BY has happened then you can utilize HAVING clause

SELECT columns
FROM table_name
WHERE condition (optional)
GROUP BY column_name
HAVING condition
ORDER BY condition (optional)

FROM personal AS p
INNER JOIN city AS c
ON p.city = c.cid
WHERE p.age>20
GROUP BY city
HAVING COUNT(p.city)>=1
ORDER BY Total;

UNION and UNION ALL

In SQL, UNION and UNION ALL are used to combine the results of two or more SELECT queries. They have some key
differences and use cases:

SQL 20
UNION
Combines the results of two or more SELECT statements.

Removes duplicate rows from the result set. It only removes duplicates when all the other parameters are same
as well. Suppose we just took names and there are 2 similar names, it would just show 1 in the table. But let’s if
we select all the parameters then it would show us two names since they might have different id, number, city.

UNION ALL

Combines the results of two or more SELECT statements.

Includes all rows from the result sets, including duplicates.

Syntax

SELECT column1, column2


FROM table1
UNION/UNION ALL
SELECT column1, column2
FROM table2;

Rules -

1. Each SELECT statement within UNION must have the same number of columns.

2. The columns must also have similar data types like INT, VARCHAR

3. The columns in each SELECT statement should be in the same order.

SELECT column1, column2


FROM table1
WHERE condition
UNION/UNION ALL
SELECT column1, column2
FROM table2
WHERE condition

Eg

SELECT name,age
FROM students
WHERE gender = "M"
UNION
SELECT name, age
FROM lecturers
WHERE gender = "M";

SELECT s.name, s.age, c.cityname


FROM students AS s
INNER JOIN city AS c
ON s.city = c.cid
WHERE c.cityname = "Delhi"
UNION ALL
SELECT l.name, l.age, ci.cityname
FROM lecturers AS l
INNER JOIN city as ci
ON l.city = ci.cid
WHERE ci.cityname = "Delhi"

CASE Clause

Syntax

SQL 21
SELECT column1, column2,
CASE
WHEN condition1 THEN RESULT1
WHEN condition2 THEN RESULT2
WHEN condition3 THEN RESULT3
ELSE result alias_name
END AS alias_name
FROM table_name;

Eg

SELECT Id, Name, Percentage,


CASE
WHEN Percentage>=80 AND Percentage<=100 THEN "Merit"
WHEN Percentage>=60 AND Percentage<80 THEN "1st division"
WHEN Percentage>=45 AND Percentage<60 THEN "2nd division"
WHEN Percentage>=33 AND Percentage<45 THEN "3rd division"
WHEN Percentage<33 THEN "Fail"
ELSE "Not correct percentage"
END AS Final_Grade
FROM student_table;

Id Name Percentage Final_Grade

1 Ram Kumar 57 2nd division

2 Salman Khan 28 Fail

3 Meera Khan 81 Merit

4 Sarita Kumari 45 2nd division

Updating multiple values using CASE clause

UPDATE student_table
SET Percentage = (CASE Id
WHEN 3 THEN 91
WHEN 2 THEN 15
END)
WHERE Id in (3,2);

Id Name Percentage Final_Grade

1 Ram Kumar 57 2nd division

2 Salman Khan 15 Fail

3 Meera Khan 91 Merit

4 Sarita Kumari 45 2nd division

SELECT with IF clause

Syntax

SELECT column1, column2,


IF (condition, TRUE Result, FALSE RESULT) AS alias_name
FROM table_name;

Eg

SELECT Id, Name, Percentage,


if(percentage>=33, "PASS", "FAIL") AS Result

SQL 22
FROM student_table;

Id Name Percentage Result

1 Ram Kumar 57 PASS

2 Salman Khan 28 FAIL

3 Meera Khan 81 PASS

4 Sarita Kumari 45 PASS

Functions in SQL

Integer Function

Integer Functions Part - I

1. MOD()

Calculates the remainder of a division between two integers.

Syntax: MOD(dividend, divisor) or dividend % divisor

Example:

SELECT MOD(10, 3); -- Output: 1


SELECT 10 % 3; -- Output: 1

2. FLOOR()

Returns the largest integer less than or equal to a given number.

Syntax: FLOOR(number)

Example:

SELECT FLOOR(5.7); -- Output: 5


SELECT FLOOR(-2.3); -- Output: -3

3. CEIL() or CEILING()

Returns the smallest integer greater than or equal to a given number.

Syntax: CEIL(number) or CEILING(number)

Example:

SELECT CEIL(5.2); -- Output: 6


SELECT CEIL(-2.8); -- Output: -2

4. ROUND()

Rounds a number to the nearest integer or to a specified number of decimal places.

Syntax: ROUND(number, decimal_places)

Example:

SELECT ROUND(5.5); -- Output: 6


SELECT ROUND(5.4); -- Output: 5
SELECT ROUND(5.678, 1); -- Output: 5.7

5. TRUNCATE()

Truncates a number to a specified number of decimal places without rounding.

Syntax: TRUNCATE(number, decimal_places)

Example:

SQL 23
SELECT TRUNCATE(5.678, 1); -- Output: 5.6
SELECT TRUNCATE(5.678, 0); -- Output: 5

Integer Functions Part - II

6. ABS()

Returns the absolute value of a number (removes the negative sign).

Syntax: ABS(number)

Example:

SELECT ABS(-10); -- Output: 10


SELECT ABS(10); -- Output: 10

7. SIGN()

Returns the sign of a number:

1 if the number is positive.

1 if the number is negative.

0 if the number is zero.

Syntax: SIGN(number)

Example:

SELECT SIGN(-25); -- Output: -1


SELECT SIGN(0); -- Output: 0
SELECT SIGN(50); -- Output: 1

8. DIV OR /

Performs integer division, discarding the remainder.

Syntax: dividend DIV divisor

Example:

SELECT 10 DIV 3; -- Output: 3


SELECT 15 DIV 4; -- Output: 3

9. POW() or POWER()

Raises an integer to the power of another integer.

Syntax: POW(base, exponent) or POWER(base, exponent)

Example:

SELECT POW(2, 3); -- Output: 8


SELECT POWER(3, 2);-- Output: 9

10. GREATEST() and LEAST()

GREATEST(): Returns the largest value among a list of integers.

LEAST(): Returns the smallest value among a list of integers.

Syntax:

GREATEST(value1, value2, ...)

LEAST(value1, value2, ...)

Example:

SQL 24
SELECT GREATEST(10, 20, 5); -- Output: 20
SELECT LEAST(10, 20, 5); -- Output: 5

String Functions

String Functions - I

1. UPPER(), UCASE() - Use for making everything in uppercase

SELECT id, UPPER(name) AS Name


FROM aditya.personal;

2. LOWER(), LCASE() - Used for making everything in lowercase

SELECT id, LOWER(name) AS Name, age


FROM aditya.personal;

3. CHAR_LENGHT() - Used for calculating the length of the string. It includes space as well.

SELECT id, name, CHAR_LENGTH(name) AS Length, age


FROM aditya.personal;

4. LENGTH() - Gives the value in bytes for how much space is occupied.

SELECT id, name, LENGTH(name) AS Characters


FROM aditya.personal;

5. CONCAT() - Can concatenate rows

SELECT id, CONCAT(name, " ", age) AS Name, gender


FROM aditya.personal;

6. RTRIM() - Can trim any space on the right side

SELECT RTRIM("Yahoo Baba ") AS Name

7. LTRIM() - Can trim any space on the left side

SELECT LTRIM(" Yahoo Baba") AS Name

8. TRIM() - Can trim the space from both left and right side

SELECT TRIM(" Yahoo Baba ") AS Name

9. POSITION() - Can tell the position of a particular word or character in the string using number

SELECT POSITION("Baba" IN "Yahoo Baba") AS Position;

10. INSTR() - It also tells the position but we don’t have to use IN

SELECT INSTR("Yahoo Baba", "Baba") AS Position;

SQL 25
11. LOCATE() - It also tells the position but the syntax is different.

SELECT LOCATE("hoo", "Yahoo Baba") AS Position;

Output will be 3

SELECT LOCATE("a", "Yahoo Baba", 3) AS Position;

12. SUBSTRING() - Gives the value of string from the number provided

SELECT SUBSTRING(string, start_position, length)

SELECT SUBSTRING("Yahoo Baba", 5) AS Name

Name

o Baba

SELECT SUBSTRING("Yahoo Baba", 7, 3) AS Name

Name

Bab

13. SUBSTRING_INDEX()
It gives us all the value before the 2nd parameter and 3rd parameter decides which 2nd parameter to
use

SELECT SUBSTRING_INDEX("www.yahoobaba.net", ".", 2) AS Name

Name

www.yahoobaba

String Functions - II

14. LEFT(Parameter1, Parameter2)

Gives us the value from left

SELECT LEFT("yahoobaba", 5) AS Name

yahoo

15. RIGHT(Parameter1, Parameter2)

SELECT RIGHT("yahoobaba", 3) AS Name

aba

16. RPAD(Parameter1, Parameter2, Parameter3)

If we want to make a certain string up to a certain length towards right side then RPAD can be utilized.
Yahoo baba combined has 10 characters, so to make it 20, we will add 10 dashes.

SELECT RPAD("Yahoo baba", 20, "-") AS Name;

Yahoo baba----------

SQL 26
17. LPAD(Parameter1, Parameter2, Parameter3)

SELECT LPAD("Yahoo baba", 20, "-") AS Name;

----------Yahoo baba

18. REVERSE()

Use for reversing the string

SELECT REVERSE(100) AS Name;

001

19. REPLACE()

SELECT REPLACE ("Yahoo Baba", "Yahoo", "Twitter") AS Name;

Twitter Baba

20. CAST()

This is utilized to convert into int format. Replace function returns in string format

CAST(__ AS SIGNED)

21. STRCMP()
Used for matching two strings

SELECT STRCMP("Yahoo Baba", "yahoo baba") AS Name

SELECT STRCMP("Yahoo Baba", "yahoo wow") AS Name

Returns 0 if the strings are equal.


Returns -1 if the first string (string1) is less than the second string (string2)
Returns 1 if the first string (string1) is greater than the second string (string

22. FIELD()

The FIELD() function in SQL is used to find the position of a value within a list of values. It is most
commonly available in MySQL. If the value does not exist in the list, the function returns 0 .

SELECT FIELD("x", "a", "k", "x", "l") AS String_Position;

23. FIND_IN_SET()

Same as field but we don’t have to leave space in between inverted commas and also don’t leave any
space in between commas (grammar works differently here)

SELECT FIND_IN_set("Ram", "Mohan,Shyam,Ram") AS String_Position;

24. HEX() (NO USAGE)


Returns value in hexadecimal form

SELECT HEX("Yahoo Baba") AS Name;

SQL 27
5961686F6F2042616261

26. REPEAT
The REPEAT() function in SQL is used to repeat a given string a specific number of times. It is a simple
but powerful function, especially when you need to generate patterns or create formatted output.

REPEAT(string, count)

Date Functions

Initial functions

For finding current time

SELECT CURRENT_TIME();

For finding current date

SELECT CURRENT_DATE()

For finding date and time together

SELECT CURRENT_TIMESTAMP()

For extracting anything - day, month, year and second, minute, hour

SELECT DAY/MONTH/YEAR/SECOND/MINUTE/HOUR('2024-12-05 22:19:44')

For extracting anything

SELECT EXTRACT(component FROM datetime_expression)


FROM table_name (optional)

Component includes

Later functions

DATEDIFF: calculates the difference between two dates

SELECT DATEDIFF(date1, date2)

SQL 28
SELECT DATEDIFF('2024-02-21', '2024-02-10')

TIMEDIFF: calculates the difference between two time

SELECT TIMEDIFF(time1, time2)

DATE_ADD: This function adds a time/date interval to a date or timestamp

SELECT DATE_ADD(date, INTERVAL value_and_interval_unit)

Eg

SELECT DATE_ADD(dob, INTERVAL 1 MONTH)

DATE_SUB: This function removes a time/date interval to a date or timestamp

SELECT DATE_SUB(date, INTERVAL value interval_unit)

Eg.

SELECT DATEDIFF(dob, INTERVAL 3 YEARS)

Last functions

DATE_FORMAT: Displays date/datetime data in different formats

SELECT DATE_FORMAT(date/datetime, format)

SELECT DATE_FORMAT('2024-03-26', '%D %M %Y');

💡 The format will always be year-month-date because SQL understands that only

SQL 29
Null Functions

IFNULL()

Introduction

Replaces ‘NULL’ with a specified value. If the value is not null, it will return whatever value is specified
like in this case value otherwise in case of null values, it will return replacement_value .

IFNULL (value, replacement_value)

Ex

first_name middle_name last_name

John William Doe

Jane null Smith

Alice Marie Johnson

Bob null Brown

SELECT
first_name,
IFNULL(middle_name, 'No middle name') AS middle_name,
last_name
FROM employees;

Explanation:
IFNULL(middle_name, 'No middle name') : If middle_name is NULL , it will return 'No middle name' instead.
Otherwise, it will return the value of middle_name .

first_name , last_name : These columns are selected as-is without any modification.

Example Output:
first_name middle_name last_name

John William Doe

Jane No middle name Smith

Alice Marie Johnson

Bob No middle name Brown

COALESCE()

SQL 30
COALESCE() is a standard SQL function used to return the first non- NULL value from a list of expressions. If all
the expressions are NULL , it returns NULL .

COALESCE(expression1, expression2, ..., expressionN)

Explanation:
expression1, expression2, ..., expressionN : These are the values or expressions you want to evaluate.
COALESCE() returns the first non- NULL expression in the list. If all expressions are NULL , it returns NULL .

Key Points:
It can take two or more arguments.

It evaluates the arguments from left to right.

It stops evaluating as soon as it finds a non- NULL value, which is returned.

If all arguments are NULL , it returns NULL .

NULLIF()

Syntax

If the value of column_name matches with expression then the value changes to null value

NULLIF(column_name, expression)

Ex

id name salary

1 John 5000

2 Alice 5000

3 Bob NULL

4 Charlie 3000

SELECT name, salary, NULLIF(salary, 5000) AS salary_after_nullif


FROM employees;

name salary salary_after_nullif

John 5000 NULL

Alice 5000 NULL

Bob NULL NULL

Charlie 3000 3000

Window Function

In SQL, a window function is a type of function that performs a calculation across a set of table rows that are
related to the current row. Unlike aggregate functions that return a single result for a group of rows, window
functions return a value for each row in the result set. This allows for more complex and nuanced queries.

Window function using aggregate functions

MAX() function

SELECT e.*, MAX(salary) over() AS max_salary


FROM parks_and_recreation.employee_salary AS e;

Using Partition by

SELECT e.*, MAX(salary) over(partition by DEPT_NAME) AS max_salary


FROM employee AS e;

SQL 31
COUNT() function

COUNT(*) —>Counts all rows in the table, regardless whether it’s null or not and their datatype

COUNT(column_name) —>Counts only that rows those have values

Needs parameters

lag()

Syntax

LAG(column_name, offset, default_value) OVER (PARTITION BY partition_column ORDER BY

SELECT e.*,
lag(SALARY,2,0) over(partition by DEPT_NAME ORDER BY emp_ID) AS lag_salary
FROM employee e;

lead()

SELECT e.*,
lag(SALARY) over(partition by DEPT_NAME ORDER BY emp_ID) AS prev_emp_salary,
lead(SALARY) over(partition by DEPT_NAME ORDER BY emp_ID) AS next_emp_salary
FROM employee e;

emp_ID emp_NAME DEPT_NAME SALARY prev_emp_salary next_emp_salary

101 Mohan Admin 4000 NULL 4000

108 Maryam Admin 4000 4000 2000

113 Gautham Admin 2000 4000 5000

120 Monica Admin 5000 2000 NULL

104 Dorvin Finance 6500 NULL 5000

106 Rajesh Finance 5000 6500 6500

Fetch a query to display if the salary of an employee is higher, lower or equal to the previous employee

SELECT e.*,
lead(salary) over(partition by DEPT_NAME ORDER BY emp_ID) as next_emp_salary,
CASE
WHEN e.SALARY>lead(salary) over(partition by DEPT_NAME ORDER BY emp_ID) THEN
WHEN e.SALARY<lead(salary) over(partition by DEPT_NAME ORDER BY emp_ID) THEN
WHEN e.SALARY=lead(salary) over(partition by DEPT_NAME ORDER BY emp_ID) THEN
END sal_comparison
FROM employee e;

first_value()

The FIRST_VALUE function in SQL is an analytic function that returns the first value in a specified ordered set
of values within a partition. It’s commonly used to pull the "first" value based on a defined order for each
partition in a result set. This function is particularly helpful when you need to retrieve the first occurrence of
a value within a group of rows while still keeping all rows in the output.

Syntax

FIRST_VALUE(column_name) OVER (
PARTITION BY partition_column
ORDER BY order_column

SQL 32
[ROWS/RANGE frame_clause]
)

SELECT *,
first_value(product_name) over(partition by product_category ORDER BY price DESC) as
FROM product p;

product_category brand product_name price most_exp_pdt

Earphone Apple AirPods Pro 280 AirPods Pro

Earphone Sony WF-1000XM4 250 AirPods Pro

Earphone Samsung Galaxy Buds Pro 220 AirPods Pro

Earphone Samsung Galaxy Buds Live 170 AirPods Pro

Headphone Apple AirPods Max 550 AirPods Max

Headphone Sony WH-1000XM4 400 AirPods Max

Headphone Microsoft Surface Headphones 2 250 AirPods Max

last_value()

The LAST_VALUE function in SQL is an analytic function that retrieves the last value in a specified ordered set
of values within a partition. It’s similar to FIRST_VALUE , but instead of getting the first item in the ordered set, it
gets the last item.

Syntax

SELECT*,
FIRST_VALUE(product_name) over(partition by product_category ORDER BY price DESC) AS
LAST_VALUE(product_name) over(partition by product_category ORDER BY price DESC
RANGE BETWEEN UNBOUNDED PRECEDING AND UNBOUNDED FOLLOWING) as most_cheap_pdt
FROM product;

Alternate way of writing window functions

SELECT*,
FIRST_VALUE(product_name) over w AS most_exp_produt,
LAST_VALUE(product_name) over w as most_cheap_pdt
FROM product
window w AS (partition by product_category ORDER BY price DESC
RANGE BETWEEN UNBOUNDED PRECEDING AND UNBOUNDED FOLLOWING);

nth_value()

The NTH_VALUE function in SQL is used to retrieve the Nth value in an ordered set of values within a window
or partition. Unlike FIRST_VALUE or LAST_VALUE , which only return the first or last value, NTH_VALUE lets you
specify which position (like 2nd, 3rd, etc.) you want to return. It takes two argument, column name and N
(The position of the value you want to retrieve)

Q. Write a query to display the second most expensive product under each category?

NTH_VALUE(column_name, N) OVER (
PARTITION BY partition_column
ORDER BY order_column
[ROWS/RANGE frame_clause]
)

SQL 33
SELECT*,
nth_value(product_name, 2) over w as second_most_exp_pdt
FROM product
window w AS (partition by product_category ORDER BY price DESC
RANGE BETWEEN UNBOUNDED PRECEDING AND UNBOUNDED FOLLOWING);

ntile()
The NTILE function in SQL is used to divide rows into a specified number of buckets or groups and assign
each row a bucket number. It’s helpful for distributing rows evenly or creating percentiles, quartiles, or other
statistical groupings.

NTILE(number_of_buckets) OVER (ORDER BY column)

Write a query to segregate all the expensive phones, mid range phones and cheaper phones

SELECT product_name,
CASE
WHEN x.buckets = 1 THEN "Expensive Phone"
WHEN x.buckets = 2 THEN "Mid Range Phone"
WHEN x.buckets = 3 THEN "Cheap Phone"
END phone_category
FROM (SELECT*,
ntile(3) over(ORDER BY price desc) AS buckets
FROM product
WHERE product_category = "Phone") AS x

Doesn’t need parameters

row_number()

This function gives the row number

SELECT e.*,
row_number() over() AS rn
FROM parks_and_recreation.employee_salary AS e

SELECT e.*,
row_number() over(partition by dept_name) AS rn
FROM employee e;

Now, I want the the names of new joiners assuming new joiners will have greater employee_id than previous
employees.

SELECT* FROM (SELECT e.*,


row_number() over(partition by dept_name ORDER BY emp_ID DESC) AS rn
FROM employee e) AS x
WHERE x.rn<3

rank()

This will provide the rank like 1, 2, 3. If the salary is same, same rank will be provided

SQL 34
SELECT e.*,
rank() over(partition by DEPT_NAME ORDER BY SALARY DESC) AS rnk
FROM employee e

120 Monica Admin 5000 1

101 Mohan Admin 4000 2

108 Maryam Admin 4000 2

113 Gautham Admin 2000 4

This can give me the values of people that have lesser rank than 4

SELECT* FROM
(SELECT e.*,
rank() over(partition by DEPT_NAME ORDER BY SALARY DESC) AS rnk
FROM employee e) AS x
WHERE x.rnk<4

120 Monica Admin 5000 1

101 Mohan Admin 4000 2

108 Maryam Admin 4000 2

dense_rank()

Only difference is the numbering as you can see in the highlighted values

SELECT e.*,
rank() over(partition by DEPT_NAME ORDER BY SALARY DESC) AS rnk,
dense_rank() over(partition by DEPT_NAME ORDER BY SALARY DESC) AS den_rnk
FROM employee e

rnk den_rnk

120 Monica Admin 5000 1 1

101 Mohan Admin 4000 2 2

108 Maryam Admin 4000 2 2

113 Gautham Admin 2000 4 3

Difference between row_number(), rank_number(), dense_rank()

SELECT e.*,
rank() over(partition by DEPT_NAME ORDER BY SALARY DESC) AS rnk,
dense_rank() over(partition by DEPT_NAME ORDER BY SALARY DESC) AS den_rnk,
row_number() over(partition by DEPT_NAME ORDER BY SALARY DESC) AS rn
FROM employee e

rnk den_rnk rn

120 Monica Admin 5000 1 1 1

101 Mohan Admin 4000 2 2 2

108 Maryam Admin 4000 2 2 3

113 Gautham Admin 2000 4 3 4

104 Dorvin Finance 6500 1 1 1

116 Satya Finance 6500 1 1 2

118 Tejaswi Finance 5500 3 2 3

SQL 35
106 Rajesh Finance 5000 4 3 4

119 Cory HR 8000 1 1 1

💡 ROW_NUMBER , RANK , and DENSE_RANK :

Are useless without ORDER BY because their primary function depends on an ordered
evaluation.

Always pair them with an ORDER BY clause in the OVER() window to ensure meaningful and
consistent results.

cume_dist()

The CUME_DIST (cumulative distribution) function in SQL is used to calculate the cumulative distribution of a
value within a partition, which means it shows how many rows have a value less than or equal to the
current row's value. It outputs a cumulative percentile rank between 0 and 1 .

CUME_DIST() OVER (
PARTITION BY partition_column
ORDER BY order_column
)

Write a query to fetch all products which are constituting the first 30% of the data in products table based
on price

SELECT product_name , cume_distribution


FROM (SELECT *,
round (cume_dist() over(ORDER BY price DESC) *100, 2) AS cume_distribution
FROM product) AS x
WHERE x.cume_distribution<=30;

percent_rank()

The PERCENT_RANK function in SQL is used to calculate the relative rank of each row as a percentage between
0 and 1 , within a partition. Unlike CUME_DIST , which gives you the cumulative distribution up to each value,
PERCENT_RANK calculates how each row ranks relative to the highest and lowest values in the partition.

PERCENT_RANK() OVER (
PARTITION BY partition_column
ORDER BY order_column
)

Q. By how much percentage is galaxy Z fold 3 is expensive as compared to other products

SELECT product_name, percentage_rank


FROM
(SELECT*,
round(percent_rank() over(ORDER BY price)*100, 2) as percentage_rank
FROM product) AS x
WHERE x.product_name = "Galaxy Z Fold 3";

Frame clause

SQL 36
Let's look at examples for all the possible frame clause types in SQL, using a sales table:

month sales

Jan 100

Feb 200

Mar 150

Apr 300

We’ll use a window function SUM(sales) to calculate different types of sums based on the frame clauses.

1. ROWS BETWEEN UNBOUNDED PRECEDING AND CURRENT ROW - by default


Meaning: The frame starts from the very first row in the partition and includes all rows up to the current row.

Query:

SELECT
month,
sales,
SUM(sales) OVER (ORDER BY month ROWS BETWEEN UNBOUNDED PRECEDING AND CURRENT RO
W) AS running_total
FROM sales;

Result:
month sales running_total

Jan 100 100

Feb 200 300

Mar 150 450

Apr 300 750

The running total includes all rows up to the current row.

2. ROWS BETWEEN 1 PRECEDING AND CURRENT ROW


Meaning: The frame includes the current row and the row immediately preceding it.

Query:

SELECT
month,
sales,
SUM(sales) OVER (ORDER BY month ROWS BETWEEN 1 PRECEDING AND CURRENT ROW) AS rol
ling_sum
FROM sales;

Result:
month sales rolling_sum

Jan 100 100

Feb 200 300

Mar 150 350

Apr 300 450

For Jan, only the current row ( 100 ).

For Feb, includes both Jan and Feb ( 100 + 200 = 300 ).

For Mar, includes both Feb and Mar ( 200 + 150 = 350 ).

SQL 37
For Apr, includes both Mar and Apr ( 150 + 300 = 450 ).

3. ROWS BETWEEN UNBOUNDED PRECEDING AND 1 FOLLOWING


Meaning: The frame starts from the very first row in the partition and includes all rows up to one row after the
current row.

Query:

SELECT
month,
sales,
SUM(sales) OVER (ORDER BY month ROWS BETWEEN UNBOUNDED PRECEDING AND 1 FOLLOWIN
G) AS future_sum
FROM sales;

Result:
month sales future_sum

Jan 100 300

Feb 200 450

Mar 150 550

Apr 300 300

For Jan, includes Jan + Feb ( 100 + 200 = 300 ).

For Feb, includes Feb + Mar ( 200 + 150 = 450 ).

For Mar, includes Mar + Apr ( 150 + 300 = 550 ).

For Apr, includes just Apr ( 300 ).

4. ROWS BETWEEN CURRENT ROW AND UNBOUNDED FOLLOWING


Meaning: The frame starts from the current row and includes all rows after the current row.

Query:

SELECT
month,
sales,
SUM(sales) OVER (ORDER BY month ROWS BETWEEN CURRENT ROW AND UNBOUNDED FOLLOWIN
G) AS future_total
FROM sales;

Result:
month sales future_total

Jan 100 850

Feb 200 650

Mar 150 450

Apr 300 300

For Jan, includes Jan + Feb + Mar + Apr ( 100 + 200 + 150 + 300 = 850 ).

For Feb, includes Feb + Mar + Apr ( 200 + 150 + 300 = 650 ).

For Mar, includes Mar + Apr ( 150 + 300 = 450 ).

For Apr, includes just Apr ( 300 ).

SQL 38
5. RANGE BETWEEN UNBOUNDED PRECEDING AND CURRENT ROW
Meaning: This is similar to ROWS BETWEEN UNBOUNDED PRECEDING AND CURRENT ROW , but it considers the values in the ORDER

BY clause rather than the row positions.

If the sales column had repeated values, RANGE would treat rows with the same sales value as part of the same
frame.

Query:

SELECT
month,
sales,
SUM(sales) OVER (ORDER BY sales RANGE BETWEEN UNBOUNDED PRECEDING AND CURRENT RO
W) AS range_sum
FROM sales;

Result (assuming sales values might repeat):


month sales range_sum

Jan 100 100

Mar 150 250

Feb 200 450

Apr 300 750

The RANGE frame uses sales values to determine the frame, not the row positions.

The result will consider all rows up to the current row where sales values are equal or lower.

6. RANGE BETWEEN CURRENT ROW AND UNBOUNDED FOLLOWING


Meaning: This includes the current row and all rows with values greater than the current row, defined by the
ORDER BY clause.

Query:

SELECT
month,
sales,
SUM(sales) OVER (ORDER BY sales RANGE BETWEEN CURRENT ROW AND UNBOUNDED FOLLOWIN
G) AS range_future_total
FROM sales;

Result:
month sales range_future_total

Jan 100 850

Mar 150 650

Feb 200 450

Apr 300 300

For Jan, includes all sales values greater than or equal to 100 .

For Feb, includes all sales values greater than or equal to 200 .

Summary of Frame Clauses


Frame Clause Meaning
ROWS BETWEEN UNBOUNDED PRECEDING AND CURRENT ROW All rows from the start of the partition to the current row.

SQL 39
ROWS BETWEEN 1 PRECEDING AND CURRENT ROW Current row and the one before it.
ROWS BETWEEN UNBOUNDED PRECEDING AND 1 FOLLOWING Current row and the next one.
ROWS BETWEEN CURRENT ROW AND UNBOUNDED FOLLOWING Current row and all rows after it.
RANGE BETWEEN UNBOUNDED PRECEDING AND CURRENT ROW All rows up to the current row based on value in ORDER BY .
RANGE BETWEEN CURRENT ROW AND UNBOUNDED FOLLOWING Current row and all rows with values greater than it.

These clauses give you control over the rows considered in the window function calculation for each row in
your result set.

WITH clause or CTE (Common Table Expression) or Sub-Query Factoring

The WITH clause in SQL, also known as a Common Table Expression (CTE), is a way to create a temporary, named
result set that you can reference within a SELECT , INSERT , UPDATE , or DELETE statement. It is particularly helpful for
breaking down complex queries into simpler, more readable parts by defining intermediate results that can be used
later in the main query.

Syntax

WITH CTE_name AS (
-- Your "scratch paper" query here
SELECT column1, column2
FROM table
WHERE condition
)
-- Main query that uses the CTE
SELECT *
FROM CTE_name;

Q.1 Fetch employees who earn more than average salary of all employees

WITH average_salary AS
(SELECT CAST(avg(salary) AS SIGNED) as avg_salary
FROM emp)
SELECT*
FROM emp e, average_salary av
WHERE e.SALARY>av.avg_salary

OR

WITH average_salary (avg_salary) AS


(SELECT CAST(avg(salary) AS SIGNED)
FROM emp)
SELECT*
FROM emp e, average_salary av
WHERE e.SALARY>av.avg_salary

💡 When you alias a CTE (or table), the alias replaces the original name for that query scope.

Use the alias everywhere in the query after defining it.

Q.2 Find stores whose sales are higher than average sales across all stores
Using normal sql query

SELECT s.store_id, SUM(cost) AS total_sales_per_store


FROM sales s
GROUP BY store_id;

SQL 40
SELECT cast(AVG(total_sales_per_store) AS SIGNED) AS avg_sales_per_store
FROM (SELECT s.store_id, SUM(cost) AS total_sales_per_store
FROM sales s
GROUP BY store_id) x;

SELECT*
FROM (SELECT s.store_id, SUM(cost) AS total_sales_per_store
FROM sales s
GROUP BY store_id) total_sales
INNER JOIN (SELECT cast(AVG(total_sales_per_store) AS SIGNED) AS avg_sales_per_store
FROM (SELECT s.store_id, SUM(cost) AS total_sales_per_store
FROM sales s
GROUP BY store_id) x) avg_sales
ON total_sales.total_sales_per_store>avg_sales.avg_sales_per_store;

Using CTE

WITH total_sales(store_id, total_cost_of_stores) AS


(SELECT s.store_id, SUM(cost) AS total_cost_of_stores
FROM sales s
GROUP BY store_id),

avg_sales(average_cost_of_stores) AS
(SELECT CAST(AVG(total_cost_of_stores) AS SIGNED) AS average_cost_of_stores
FROM total_sales)

SELECT*
FROM total_sales ts
INNER JOIN avg_sales av
ON ts.total_cost_of_stores>av.average_cost_of_stores;

SubQuery or Nested Query

Syntax

SELECT columns
FROM table1
WHERE
column = (SELECT columns FROM table2 WHERE condition);

Eg

SELECT*
FROM aditya.personal
WHERE city = (SELECT cid FROM city WHERE cityname = "Agra");

Recursive SQL queries


In MySQL, recursion in SQL queries is typically done through Recursive Common Table Expressions (CTEs), which
allow you to perform self-referencing queries. WITH RECURSIVE CTEs make it possible to work with hierarchical or tree-
like data structures, such as organizational charts, directory structures, or parent-child relationships in data.

How Recursive CTEs Work


A recursive CTE is defined with two main parts:

1. Anchor Member: The initial part of the CTE, which serves as the base case (the starting point for recursion).

SQL 41
2. Recursive Member: A query that refers to the CTE itself, which allows it to call itself repeatedly until a stopping
condition is met.

The recursive CTE runs the anchor member first, which gets the initial set of rows. Then, it runs the recursive
member repeatedly, each time with the results from the previous iteration, until no new rows are added.

WITH RECURSIVE cte_name AS


(SELECT query (Non-recursive or base query)
UNION
SELECT query (Recursive query using cte_name [with a termination condition])

SELECT*
FROM cte_name;

Q. Write a sql query to find the numbers from 1 to 10

WITH RECURSIVE numbers AS


(SELECT 1 AS n
UNION
SELECT n+1
FROM numbers
WHERE n+1<11)

SELECT*
FROM numbers;

Q. Write a sql query for for finding the employee hierarchy starting from Asha
This is the existing table:

id name manager_id salary designation

1 Shripadh 10000 CEO

2 Satya 5 1400 Software Engineer

3 Jia 5 500 Data Analyst

4 David 5 1800 Data Scientist

5 Michael 7 3000 Manager

6 Arvind 7 2400 Architect

7 Asha 1 4200 CTO

8 Maryam 1 3500 Manager

9 Reshma 8 2000 Business Analyst

10 Akshay 8 2500 Java Developer

WITH RECURSIVE employee_hierarchy AS


( SELECT id, name, manager_id, designation, 1 as lvl
FROM emp_details
WHERE name = 'Asha'
UNION
SELECT D.id, D.name, D.manager_id, D.designation, H.lvl+1
FROM employee_hierarchy H
JOIN emp_details D
ON H.id = D.manager_id)

SELECT H2.id AS emp_id, H2.name AS emp_name, D2.name AS manager_name, H2.lvl AS level


FROM employee_hierarchy H2

SQL 42
JOIN emp_details D2
ON D2.id = H2.manager_id;

emp_id emp_name manager_id level

7 Asha Shripadh 1

5 Michael Asha 2

6 Arvind Asha 2

2 Satya Michael 3

3 Jia Michael 3

4 David Michael 3

Q. Find the hierarchy of manager for a given employee

Procedure in SQL

Block of code that is stored in database

Procedure can do things that normal SQL query can’t do

create table products


(
product_code varchar(20) primary key,
product_name varchar(100),
price float,
quantity_remaining int,
quantity_sold int
);

create table sales


(
order_id int auto_increment primary key,
order_date date,
product_code varchar(20) references products(product_code),
quantity_ordered int,
sale_price float
);

insert into products (product_code,product_name,price,quantity_remaining,quantity_sold)


values ('P1', 'iPhone 13 Pro Max', 1000, 5, 195);

insert into sales (order_date,product_code,quantity_ordered,sale_price)


values (str_to_date('10-01-2022','%d-%m-%Y'), 'P1', 100, 120000);
insert into sales (order_date,product_code,quantity_ordered,sale_price)
values (str_to_date('20-01-2022','%d-%m-%Y'), 'P1', 50, 60000);
insert into sales (order_date,product_code,quantity_ordered,sale_price)
values (str_to_date('05-02-2022','%d-%m-%Y'), 'P1', 45, 540000);

drop procedure if exists pr_buy_products;

DELIMITER $$
create procedure pr_buy_products()
begin
declare v_product_code varchar(20);
declare v_price int;

select product_code, price


into v_product_code, v_price

SQL 43
from products
where product_name = 'iPhone 13 Pro Max';

insert into sales (order_date,product_code,quantity_ordered,sale_price)


values (cast(now() as date), v_product_code, 1, (v_price * 1));

update products
set quantity_remaining = (quantity_remaining - 1)
, quantity_sold = (quantity_sold + 1)
where product_code = v_product_code;

select 'Product sold!';


end$$

call pr_buy_products()

Questions

Question 1

Query the list of CITY names from STATION which have vowels (i.e., a, e, i, o, and u) as both their first and last
characters. Your result cannot contain duplicates.

SELECT DISTINCT CITY


FROM STATION
WHERE CITY REGEXP '^[AEIOUaeiou].*[AEIOUaeiou]$';

REGEXP '^[AEIOUaeiou].*[AEIOUaeiou]$':
^ asserts the start of the string.
[AEIOUaeiou] matches any vowel at the start or end.
.* matches any characters in between.
$ asserts the end of the string.

Question 2
Query the list of CITY names from STATION that do not start with vowels. Your result cannot contain duplicates.

SELECT DISTINCT CITY


FROM STATION
WHERE CITY NOT REGEXP '^[AEIOUaeiou]';

Question 3

Query the list of CITY names from STATION that either do not start with vowels or do not end with vowels. Your
result cannot contain duplicates.

SELECT DISTINCT CITY


FROM STATION
WHERE CITY NOT REGEXP '^[AEIOUaeiou]' OR CITY NOT REGEXP '[AEIOUaeiou]$';

Question 4

Query the Name of any student in STUDENTS who scored higher than 75 Marks. Order your output by the last
three characters of each name. If two or more students both have names ending in the same last three
characters (i.e.: Bobby, Robby, etc.), secondary sort them by ascending ID.

SQL 44
SELECT Name
FROM STUDENTS
WHERE Marks > 75
ORDER BY RIGHT (Name, 3), ID;

Question 5

Samantha was tasked with calculating the average monthly salaries for all employees in the EMPLOYEES table,
but did not realize her keyboard's key was broken until after completing the calculation. She wants your help
finding the difference between her miscalculation (using salaries with any zeros removed), and the actual
average salary.

Write a query calculating the amount of error (i.e.: average monthly salaries), and round it up to the next
integer. The EMPLOYEES table is described.

SELECT
CEIL(AVG(Salary) - AVG(CAST(REPLACE(Salary, '0', '') AS UNSIGNED))) AS error
FROM EMPLOYEES;

Join Question

Question 1

+---------------+---------+
| Column Name | Type |
+---------------+---------+
| id | int |
| recordDate | date |
| temperature | int |
+---------------+---------+
id is the column with unique values for this table.
There are no different rows with the same recordDate.
This table contains information about the temperature on a certain day.

Write a solution to find all dates' Id with higher temperatures compared to its previous dates (yesterday).
Return the result table in any order.

SELECT w1.id
FROM Weather AS w1
INNER JOIN Weather AS w2
ON DATEDIFF(w1.recordDate, w2.recordDate) = 1
WHERE w1.temperature>w2.temperature;

EY questions

Q.1 Write an sql query to find the count of three consecutive numbers.

Table

CREATE TABLE logs (


`id` INT NOT NULL,
`num` INT NULL,
PRIMARY KEY (`id`));

insert into logs values


(1, 1),
(2, 1),
(3, 1),
(4, 2),

SQL 45
(5, 1),
(6, 2),
(7, 2);

Code

WITH cte AS
(SELECT num,
lead(num, 1) over() AS 2nd_num,
lead(num, 2) over() as 3rd_num
FROM logs )

SELECT COUNT(num=2nd_num AND 2nd_num=3rd_num) AS consecutive_number


FROM cte
WHERE num=2nd_num AND 2nd_num=3rd_num

Q.2 Write a sql query to find the average revenue by each sector on a monthly basis

Table

CREATE TABLE Transactions (


transaction_id INT PRIMARY KEY,
company_id INT,
transaction_date DATE,
revenue DECIMAL(10, 2)
);
INSERT INTO Transactions (transaction_id, company_id, transaction_date, revenue) VAL
(101, 1, '2020-01-15', 5000.00),
(102, 2, '2020-01-20', 8500.00),
(103, 1, '2020-02-10', 4500.00),
(104, 3, '2020-02-20', 9900.00),
(105, 2, '2020-02-25', 7500.00);

--Sectors

CREATE TABLE Sectors (


company_id INT PRIMARY KEY,
sector VARCHAR(50)
);
INSERT INTO Sectors (company_id, sector) VALUES
(1, 'Technology'),
(2, 'Healthcare'),
(3, 'Technology');

WITH cte AS
(SELECT*,
CASE
WHEN transaction_date BETWEEN '2020-01-01' AND '2020-01-31' THEN 1
WHEN transaction_date BETWEEN '2020-02-01' AND '2020-02-28' THEN 2
END AS month
FROM transactions)
SELECT DISTINCT c.month, s.sector, AVG(revenue) OVER(partition by month, sector) AS
FROM cte c
LEFT JOIN Sectors s
ON s.company_id = c.company_id

SQL 46
Zomato Questions

Find city wise customers count who have placed more than three orders in November 2023.

CREATE TABLE zomato_orders(


order_id INT PRIMARY KEY,
customer_id INT,
order_date DATE,
price FLOAT,
city VARCHAR(25)
);

-- Insert sample records into the zomato_orders table


INSERT INTO zomato_orders (order_id, customer_id, order_date, price, city) VALUES
(1, 101, '2023-11-01', 150.50, 'Mumbai'),
(2, 102, '2023-11-05', 200.75, 'Delhi'),
(3, 103, '2023-11-10', 180.25, 'Mumbai'),
(4, 104, '2023-11-15', 120.90, 'Delhi'),
(5, 105, '2023-11-20', 250.00, 'Mumbai'),
(6, 108, '2023-11-25', 180.75, 'Gurgoan'),
(7, 107, '2023-12-30', 300.25, 'Delhi'),
(8, 108, '2023-12-02', 220.50, 'Gurgoan'),
(9, 109, '2023-11-08', 170.00, 'Mumbai'),
(10, 110, '2023-10-12', 190.75, 'Delhi'),
(11, 108, '2023-10-18', 210.25, 'Gurgoan'),
(12, 112, '2023-11-24', 280.50, 'Mumbai'),
(13, 113, '2023-10-29', 150.00, 'Mumbai'),
(14, 103, '2023-11-03', 200.75, 'Mumbai'),
(15, 115, '2023-10-07', 230.90, 'Delhi'),
(16, 116, '2023-11-11', 260.00, 'Mumbai'),
(17, 117, '2023-11-16', 180.75, 'Mumbai'),
(18, 102, '2023-11-22', 320.25, 'Delhi'),
(19, 103, '2023-11-27', 170.50, 'Mumbai'),
(20, 102, '2023-11-05', 220.75, 'Delhi'),
(21, 103, '2023-11-09', 300.25, 'Mumbai'),
(22, 101, '2023-11-15', 180.50, 'Mumbai'),
(23, 104, '2023-11-18', 250.75, 'Delhi'),
(24, 102, '2023-11-20', 280.25, 'Delhi'),
(25, 117, '2023-11-16', 180.75, 'Mumbai'),
(26, 117, '2023-11-16', 180.75, 'Mumbai'),
(27, 117, '2023-11-16', 180.75, 'Mumbai'),
(28, 117, '2023-11-16', 180.75, 'Mumbai');

WITH cte AS (
SELECT customer_id, city, order_date, COUNT(order_id) OVER(PARTITION BY customer_id) A
FROM zomato_orders)
SELECT DISTINCT customer_id, city, no_of_orders
FROM cte
WHERE no_of_orders>3 and YEAR(order_date) = 2023

SQL 47

You might also like