0% found this document useful (0 votes)
7 views44 pages

Dbms Unit III Notes

The document outlines the basic structure of SQL queries, detailing components such as SELECT, FROM, WHERE, GROUP BY, HAVING, ORDER BY, and LIMIT. It also explains the use of SQL operators like UNION, INTERSECT, and EXCEPT for combining and filtering result sets from multiple tables. Examples are provided to illustrate how these components and operators work in practice.

Uploaded by

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

Dbms Unit III Notes

The document outlines the basic structure of SQL queries, detailing components such as SELECT, FROM, WHERE, GROUP BY, HAVING, ORDER BY, and LIMIT. It also explains the use of SQL operators like UNION, INTERSECT, and EXCEPT for combining and filtering result sets from multiple tables. Examples are provided to illustrate how these components and operators work in practice.

Uploaded by

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

The basic structure of an SQL query consists of several components:

1. SELECT: The SELECT statement specifies the columns or fields that you want to retrieve
from the database table. You can select specific columns or use the asterisk (*) to select all
columns.

Example:

SELECT column1, column2 FROM table_name;

2. FROM: The FROM clause indicates the table or tables from which you want to retrieve the
data. It specifies the name of the table or tables separated by commas.

Example:

SELECT column1, column2 FROM table1, table2;

3. WHERE: The WHERE clause is used to specify conditions that filter the rows returned by
the query. It allows you to define criteria that the data must meet to be included in the result
set.

Example:

SELECT column1, column2 FROM table_name WHERE condition;

4. GROUP BY: The GROUP BY clause is used to group rows based on one or more
columns. It is often used in conjunction with aggregate functions like SUM, COUNT, AVG,
etc.

Example:

SELECT column1, SUM(column2) FROM table_name GROUP BY column1;


5. HAVING: The HAVING clause is used to specify conditions for the grouped rows after
the GROUP BY clause has been applied. It filters the groups based on the specified
conditions.

Example:

SELECT column1, SUM(column2) FROM table_name GROUP BY column1 HAVING


condition;

6. ORDER BY: The ORDER BY clause is used to sort the result set based on one or more
columns. It can sort in ascending (ASC) or descending (DESC) order.

Example:

SELECT column1, column2 FROM table_name ORDER BY column1 ASC, column2


DESC;
7. LIMIT: The LIMIT clause is used to restrict the number of rows returned by the query. It
specifies the maximum number of rows to be retrieved.

Example:

SELECT column1, column2 FROM table_name LIMIT 10;


The SQL UNION Operator

The UNION operator is used to combine the result-set of two or more SELECT statements.

 Every SELECT statement within UNION must have the same number of columns
 The columns must also have similar data types
 The columns in every SELECT statement must also be in the same order

UNION Syntax
SELECT column_name(s) FROM table1
UNION
SELECT column_name(s) FROM table2;
UNION ALL Syntax

The UNION operator selects only distinct values by default. To allow duplicate values,
use UNION ALL:

SELECT column_name(s) FROM table1


UNION ALL
SELECT column_name(s) FROM table2;

Note: The column names in the result-set are usually equal to the column names in the
first SELECT statement.

SQL UNION Example

The following SQL statement returns the cities (only distinct values) from both the
"Customers" and the "Suppliers" table:

Example:
SELECT City FROM Customers
UNION
SELECT City FROM Suppliers
ORDER BY City;
o/p:
City

Aachen
Annecy
Bend
Berlin
Cork
Delhi

INTERSECT in SQL
The INTERSECT operator in SQL is used to retrieve the records that are identical/common
between the result sets of two SELECT (tables) statements.
In real-time scenarios, there will be a huge number of tables in a database that contains
information. The user may find it challenging to gather common information from various
tables. So we use the INTERSECT operator to accomplish that. It helps to retrieve the
common data from various tables.
Syntax
To retrieve identical records from two different tables, we use the following syntax
SELECT column1, column2,…, columnN
FROM table1, table2,…, tableN
INTERSECT
SELECT column1, column2,…, columnN
FROM table1, table2,…, tableN
Example
First of all, let us create a table named “STUDENTS” using the following query −
SQL> CREATE TABLE STUDENTS(
ID INT NOT NULL,
NAME VARCHAR(20) NOT NULL,
HOBBY VARCHAR(20) NOT NULL,
AGE INT NOT NULL,
PRIMARY KEY(ID)
);
Once the table is created, let us insert some values to the table using the query below −

Let us verify whether the table “STUDENTS” is created or not using the following query −

SQL> SELECT * FROM STUDENTS;


As we can see in the below output, the table has been created in the database.
+-----+----------+--------------+-------+
| ID | NAME | HOBBY | AGE |
+-----+----------+--------------+-------+
| 1 | Vijay | Cricket | 18 |
| 2 | Varun | Football | 26 |
| 3 | Surya | Cricket | 19 |
| 4 | Karthik | Cricket | 25 |
| 5 | Sunny | Football | 26 |
| 6 | Dev | Cricket | 23
Let us create another table “ASSOCIATES” using the following query –
SQL> CREATE TABLE ASSOCIATES(
ID INT NOT NULL,
NAME VARCHAR(20) NOT NULL,
SUBJECT VARCHAR(20) NOT NULL,
AGE INT NOT NULL,
HOBBY VARCHAR(20) NOT NULL,
PRIMARY KEY(ID)
);
Let’s insert some values into the table using the following query –
SQL> INSERT INTO ASSOCIATES(ID, NAME, SUBJECT, AGE, HOBBY) VALUES(1,
'Naina', 'Maths', 24, 'Cricket');
INSERT INTO ASSOCIATES(ID, NAME, SUBJECT, AGE, HOBBY) VALUES(2, 'Varun',
'Physics', 26, 'Football');
INSERT INTO ASSOCIATES(ID, NAME, SUBJECT, AGE, HOBBY) VALUES(3, 'Dev',
'Maths', 23, 'Cricket');
INSERT INTO ASSOCIATES(ID, NAME, SUBJECT, AGE, HOBBY) VALUES(4, 'Priya',
'Physics', 25, 'Cricket');
INSERT INTO ASSOCIATES(ID, NAME, SUBJECT, AGE, HOBBY) VALUES(5,
'Aditya', 'Chemistry', 21, 'Cricket');
INSERT INTO ASSOCIATES(ID, NAME, SUBJECT, AGE, HOBBY) VALUES(6,
'Kalyan', 'Maths', 30, 'Football');
Let us verify whether the table “ASSOCIATES” is created or not using the following query

SQL> SELECT * FROM ASSOCIATES;
As we can see in the below output, the table has been created in the database.
+-----+----------+---------------+-------+----------+
| ID | NAME | SUBJECT | AGE | HOBBY |
+-----+----------+---------------+-------+----------+
| 1 | Naina | Mathematics | 24 | Cricket |
| 2 | Varun | Physics | 26 | Football |
| 3 | Dev | Mathematics | 23 | Cricket |
| 4 | Priya | Physics | 25 | Cricket |
| 5 | Adithya | Chemistry | 21 | Cricket |
| 6 | Kalyan | Mathematics | 30 | Football |
Now, we are trying to retrieve the common records from both the tables using the following
query –
SQL> SELECT NAME, AGE, HOBBY FROM STUDENTS
INTERSECT
SELECT NAME, AGE, HOBBY FROM ASSOCIATES
Output
When we execute the above query, the output is obtained as follows −
+-----------+-------+----------+
| NAME | AGE | HOBBY |
+-----------+-------+----------+
| Dev | 23 | Cricket |
| Varun | 26 | Football |
+-----------+-------+----------+
INTERSECT with BETWEEN operator
As we discussed in the initial syntax, we can also use the INTERSECT operator along with
conditional operators.
We can use the INTERSECT operator with the BETWEEN operator in SQL to find rows that
fall within a specified range.
Example
Now, let us retrieve the records that are common in both tables. In addition; we are retrieving
the records who are aged between 25 and 30 using the following query.
SQL> SELECT NAME, AGE, HOBBY FROM STUDENTS
WHERE AGE BETWEEN 25 AND 30

INTERSECT

SELECT NAME, AGE, HOBBY FROM ASSOCIATES


WHERE AGE BETWEEN 20 AND 30
Output
The output for the above query is produced as given below −
+-----------+-------+----------+
| NAME | AGE | HOBBY |
+-----------+-------+----------+
| Varun | 26 | Football |
+-----------+-------+----------+
INTERSECT with IN operator
We can also use the INTERSECT operator with the IN operator in SQL to find the common
rows that have the specified values. The IN operator is used to filter a result set based on a list
of specified values.
Example
Here, we are trying to retrieve the common records from both tables. In addition; we are
using the IN operator to retrieve the records whose hobby is ‘Cricket’.
SQL> SELECT NAME, AGE, HOBBY FROM STUDENTS
WHERE HOBBY IN('Cricket')

INTERSECT

SELECT NAME, AGE, HOBBY FROM ASSOCIATES


WHERE HOBBY IN('Cricket')
Output
When we execute the above query, the output is obtained as follows −
+-----------+-------+----------+
| NAME | AGE | HOBBY |
+-----------+-------+----------+
| Dev | 26 | Cricket
INTERSECT with LIKE operator
The LIKE operator is used to perform pattern matching on a string. The INTERSECT
operator can also be used with the LIKE operator in SQL to find the common rows that
matches with the specified pattern.
Example
Let us use the wildcard ‘%’ with the LIKE operator to retrieve the names which starts with
‘v’ from the common names of both tables.
SQL> SELECT NAME, AGE, HOBBY FROM STUDENTS
WHERE NAME LIKE 'v%'

INTERSECT

SELECT NAME, AGE, HOBBY FROM ASSOCIATES


WHERE NAME LIKE 'v%'
Output
The output for the above query is produced as given below −
+-----------+-------+----------+
| NAME | AGE | HOBBY |
+-----------+-------+----------+
| Varun | 26 | Football

EXCEPT:
The EXCEPT operator in SQL is used to retrieve the unique records that exist in the first
table, not the common records of both tables. This operator acts as the opposite of the SQL
UNION operator.
For better understanding consider two tables with records as shown in the following image −
If we perform the EXCEPT operator on the above two tables to retrieve the names, it will
display the records only from the first table which are not in common with the records of the
second table.
Here, “Dev” is common in both tables. So, the EXECPT operator will eliminate it and
retrieves only “Sara” and “Jay” as output.
Syntax
Following is the syntax of the EXCEPT operator in SQL −
SELECT column1, column2,…, columnN
FROM table1, table2,…, tableN
[Conditions] //optional
EXCEPT
SELECT column1, column2,…, columnN
FROM table1, table2,…, tableN
[Conditions] //optional
Note − The number and order of columns in both SELECT statements should be the same.
Example
First of all, let us create a table named “STUDENTS” using the following query −
SQL> CREATE TABLE STUDENTS(
ID INT NOT NULL,
NAME VARCHAR(20) NOT NULL,
HOBBY VARCHAR(20) NOT NULL,
AGE INT NOT NULL,
PRIMARY KEY(ID)
);
Once the table is created, let us insert some values to the table using the query below –
SQL> INSERT INTO STUDENTS(ID, NAME, HOBBY, AGE) VALUES(1, 'Vijay',
'Cricket', 18);
INSERT INTO STUDENTS(ID, NAME, HOBBY, AGE) VALUES(2, 'Varun', 'Football',
26);
INSERT INTO STUDENTS(ID, NAME, HOBBY, AGE) VALUES(3, 'Surya', 'Cricket', 19);
INSERT INTO STUDENTS(ID, NAME, HOBBY, AGE) VALUES(4, 'Karthik', 'Cricket',
25);
INSERT INTO STUDENTS(ID, NAME, HOBBY, AGE) VALUES(5, 'Sunny', 'Football',
26);
INSERT INTO STUDENTS(ID, NAME, HOBBY, AGE) VALUES(6, 'Dev', 'Cricket', 23);
Let us verify whether the table “STUDENTS” is created or not using the following query −
SQL> SELECT * FROM STUDENTS;
As we can see in the below output, the table has been created in the database.
+-----+----------+--------------+-------+
| ID | NAME | HOBBY | AGE |
+-----+----------+--------------+-------+
| 1 | Vijay | Cricket | 18 |
| 2 | Varun | Football | 26 |
| 3 | Surya | Cricket | 19 |
| 4 | Karthik | Cricket | 25 |
| 5 | Sunny | Football | 26 |
| 6 | Dev | Cricket | 23 |
+-----+----------+--------------+-------+

Let us create another table named “ASSOCIATES” using the following query −
SQL> CREATE TABLE ASSOCIATES(
ID INT NOT NULL,
NAME VARCHAR(20) NOT NULL,
SUBJECT VARCHAR(20) NOT NULL,
AGE INT NOT NULL,
HOBBY VARCHAR(20) NOT NULL,
PRIMARY KEY(ID)
);

Once the table is created, let us insert some values to the table using the query below −

SQL> INSERT INTO ASSOCIATES(ID, NAME, SUBJECT, AGE, HOBBY) VALUES(1,


'Naina', 'Maths', 24, 'Cricket');
INSERT INTO ASSOCIATES(ID, NAME, SUBJECT, AGE, HOBBY) VALUES(2, 'Varun',
'Physics', 26, 'Football');
INSERT INTO ASSOCIATES(ID, NAME, SUBJECT, AGE, HOBBY) VALUES(3, 'Dev',
'Maths', 23, 'Cricket');
INSERT INTO ASSOCIATES(ID, NAME, SUBJECT, AGE, HOBBY) VALUES(4, 'Priya',
'Physics', 25, 'Cricket');
INSERT INTO ASSOCIATES(ID, NAME, SUBJECT, AGE, HOBBY) VALUES(5,
'Aditya', 'Chemistry', 21, 'Cricket');
INSERT INTO ASSOCIATES(ID, NAME, SUBJECT, AGE, HOBBY) VALUES(6,
'Kalyan', 'Maths', 30, 'Football');
Let us verify whether the table “ASSOCIATES” is created or not using the following query
− SQL> SELECT * FROM ASSOCIATES;
As we can see in the below output, the table has been created in the database.
+-----+----------+---------------+-------+----------+
| ID | NAME | SUBJECT | AGE | HOBBY |
+-----+----------+---------------+-------+----------+
| 1 | Naina | Mathematics | 24 | Cricket |
| 2 | Varun | Physics | 26 | Football |
| 3 | Dev | Mathematics | 23 | Cricket |
| 4 | Priya | Physics | 25 | Cricket |
| 5 | Adithya | Chemistry | 21 | Cricket |
| 6 | Kalyan | Mathematics | 30 | Football |
+-----+----------+--------------+-------+----------

Let us retrieve the records that are only unique in the first table using the below query –
SQL> SELECT NAME, HOBBY, AGE
FROM STUDENTS

EXCEPT

SELECT NAME, HOBBY, AGE


FROM ASSOCIATES
Output
When we execute the above query, the output is obtained as follows −
+-----------+--------------+-------+
| NAME | HOBBY | AGE |
+-----+----------+---------+-------+
| Karthik | Cricket | 25 |
| Sunny | Football | 26 |
| Surya | Cricket | 19 |
| Vijay | Cricket | 18 |
+-----------+--------------+-------+
EXCEPT with BETWEEN operator
As we discussed in the initial syntax, we can also use the EXCEPT operator along with
conditional operators. We can use the EXCEPT operator with the BETWEEN operator in
SQL to exclude rows that fall within a specified range.
Example
Let us retrieve the records that are only unique in the first table. In addition; we are retrieving
the records who are aged between 20 and 30 using the following query.
SQL> SELECT NAME, HOBBY, AGE
FROM STUDENTS
WHERE AGE BETWEEN 20 AND 30

EXCEPT

SELECT NAME, HOBBY, AGE


FROM ASSOCIATES
WHERE AGE BETWEEN 20 AND 30
Output
When we execute the program query, the output is obtained as follows −
+----------+----------+-----+
| NAME | HOBBY | AGE |
+----------+----------+-----+
| Karthik | Cricket | 25 |
| Sunny | Football | 26 |
+----------+----------+-----+
Except with IN operator
We can also use the EXCEPT operator with the IN operator in SQL to exclude rows that have
the specified values. The IN operator is used to filter a result set based on
a list of specified values.
Example
Here, we are fetching the records that are only unique in the first table. In addition; we are
using the IN operator to retrieve the records whose hobby is ‘Cricket’.
SQL> SELECT NAME, HOBBY, AGE FROM STUDENTS
WHERE HOBBY IN('Cricket')

EXCEPT

SELECT NAME, HOBBY, AGE FROM ASSOCIATES


WHERE HOBBY IN('Cricket')
Output
When we execute the above query, the output is obtained as follows −
+-----------+--------------+-------+
| NAME | HOBBY | AGE |
+-----+----------+---------+-------+
| Karthik | Cricket | 25 |
| Surya | Cricket | 19 |
| Vijay | Cricket | 18 |
EXCEPT with LIKE operator
The EXCEPT operator can also be used with the LIKE operator in SQL to exclude rows that
matches with the specified pattern. The LIKE operator is used to perform pattern matching on
a string.
Example
Let us use the wildcard ‘%’ with the LIKE operator to retrieve the names which starts with
‘v’ from the result set of first SELECT statement.
SQL> SELECT NAME, AGE, HOBBY FROM STUDENTS
WHERE NAME LIKE 'v%'

EXCEPT

SELECT NAME, AGE, HOBBY FROM ASSOCIATES


WHERE NAME LIKE 'v%'
Output
The output for the above query is produced as given below −
+-----------+-------+----------+
| NAME | AGE | HOBBY |
+-----------+-------+----------+
| Vijay | 18 | Cricket |
+-----------+-------+----------+
Definition of Nested Query :

Query written inside a query is called as SQL Nested Query


The user has question in mind that the query inside query will be Select query or any other
query.There are Four types of nested queries.

1.Nested Queries with Select Statement


2.Nested Queries with Insert Statement
3.Nested Queries with Update Statement
4.Nested Queries with Delete Statement.

These are some most important types of Nested queries which we will look with example in
next sections.

How to Write SQL Nested Queries :


Bullet-points needs to be considered while writing nested Queries :

1.The SQL Nested Query will be always enclosed inside the parentheses.

2.Nested sub-query can have only one column in select clause.


3.Order by clause is restricted in query which is inner query but outer query or main query
can use order by clause.

4.User needs to take care of multiple rows operator (IN,ANY) if sub-query will return more
than one rows.

5.Between–And Operator can not be used inside the Nested Query.

Type 1 : SQL Nested Queries with Select Statement

There are so many business situations where user needs to use nested subqueries to fetch the
exact data from two or more tables.It is also called as Inline view in SQL.

Syntax :
Select Column1,Column2… From Table_Name

Where Column_Name Operator

(Select Column1,Column2…. From Table_Name_2)…

Operator (Select Column1,Column2…..From Table_Name_3)…

;
The user can use N Number of Inner Queries to fetch the required output. But using nesting
of Queries is not a good practice for performance tuning perspective.

Real Life Examples of Nested Queries :


Following are two tables,

Employee Table :

Employee No Employee Name Department

1 Rohan SQL

2 Rajiv PL SQL

3 Ram Java

Salary Table :
Employee No Salary

1 25000
2 35000

3 45000

If user wants to fetch the all records of Employees who’s salary is greater that 25000.

In this case user needs to go for Nested Query.

Query :
Select * from Employee where Employee_No

In (Select Employee_No From Salary where Salary > 25000);

The Above Query is nested query which will give you the Employees data whose salary is
greater than 25000.

Type 2 : SQL Nested Queries with Insert Statement

There are so many real life situations where user needs to use nested queries to insert the data
in table. So many times user needs to use the testing and will need some special data.To
tackle this situation Nested Queries with Insert statements will work.

Syntax :
Insert in to Tablename

(Select Column_1,Column2….From Tablename_1);

Real Life Example :


Let us consider the same tables given in Select Statement nested queries. User has created the
replica of Employee table and needs the data where salary is greater than 25000. The
Employee table replica name is Employee_Bkp.

Query :
Insert in to Employee_Bkp

(Select * from Employee where Employee_No

In (Select Employee_No From Salary where Salary > 25000));


The above nested query will help user to insert the required data in Employee_Bkp table.
Inn
er and Outer Query
Type 3 : SQL Nested Queries with Update Statement

There are sometimes user needs to update the data according to client requirements.If the data
is not huge then user can use the nested queries to update the data.

Syntax :
Update Table Set Column_name =

(Select column1,Column2….From table);

Real Life Example :


I would like you to refer the above two tables only. User wants to change the name of
Employee to Amit where Salary of that Employee is 25000.

Update Employee Set Name =

Select ‘Amit’ from Employee where Employee_No

= (Select Employee_No From Salary where Salary = 25000));


The above query will help you to update name to ‘Amit’.

Type 4 : SQL Nested Queries with Delete Statement

Sometimes user needs to delete the data with specific condition.So to delete the data with
condition user needs to use Delete nested queries.

Syntax :
Delete from tablename

Where Column_Name Operator

(Select Columnname1,Columnname2… from Tablename2);


Real Life Example :

We need to delete data from Employee table where salary is greater than 25000.

Query :
Delete from Employee where Employee_No IN

( Select Employee_No From Salary where Salary > 25000 );


The above statement will delete the data from Employee table where salary is greater than
25000

SQL Aggregate Functions


o SQL aggregation function is used to perform the calculations on multiple rows of a
single column of a table. It returns a single value.
o It is also used to summarize the data.

Types of SQL Aggregation Function

1. COUNT FUNCTION

o COUNT function is used to Count the number of rows in a database table. It can work
on both numeric and non-numeric data types.
o COUNT function uses the COUNT(*) that returns the count of all the rows in a
specified table. COUNT(*) considers duplicate and Null.

Syntax
1. COUNT(*)
2. or
3. COUNT( [ALL|DISTINCT] expression )

Sample table:

PRODUCT_MAST

PRODUCT COMPANY QTY RATE COST

Item1 Com1 2 10 20

Item2 Com2 3 25 75

Item3 Com1 2 30 60

Item4 Com3 5 10 50

Item5 Com2 2 20 40

Item6 Cpm1 3 25 75

Item7 Com1 5 30 150

Item8 Com1 3 10 30

Item9 Com2 2 25 50

Item10 Com3 4 30 120

Example: COUNT()

1. SELECT COUNT(*)
2. FROM PRODUCT_MAST;

Output:

10

Example: COUNT with WHERE


1. SELECT COUNT(*)
2. FROM PRODUCT_MAST;
3. WHERE RATE>=20;

Output:

Example: COUNT() with DISTINCT

1. SELECT COUNT(DISTINCT COMPANY)


2. FROM PRODUCT_MAST;

Output:

Example: COUNT() with GROUP BY

1. SELECT COMPANY, COUNT(*)


2. FROM PRODUCT_MAST
3. GROUP BY COMPANY;

Output:

Com1 5
Com2 3
Com3 2

Example: COUNT() with HAVING

1. SELECT COMPANY, COUNT(*)


2. FROM PRODUCT_MAST
3. GROUP BY COMPANY
4. HAVING COUNT(*)>2;

Output:

Com1 5
Com2 3

2. SUM Function

Sum function is used to calculate the sum of all selected columns. It works on numeric fields
only.
Syntax

1. SUM()
2. or
3. SUM( [ALL|DISTINCT] expression )

Example: SUM()

1. SELECT SUM(COST)
2. FROM PRODUCT_MAST;

Output:

670

Example: SUM() with WHERE

1. SELECT SUM(COST)
2. FROM PRODUCT_MAST
3. WHERE QTY>3;

Output:

320

Example: SUM() with GROUP BY

1. SELECT SUM(COST)
2. FROM PRODUCT_MAST
3. WHERE QTY>3
4. GROUP BY COMPANY;

Output:

Com1 150
Com2 170

Example: SUM() with HAVING

1. SELECT COMPANY, SUM(COST)


2. FROM PRODUCT_MAST
3. GROUP BY COMPANY
4. HAVING SUM(COST)>=170;
Output:

Com1 335
Com3 170

3. AVG function

The AVG function is used to calculate the average value of the numeric type. AVG function
returns the average of all non-Null values.

Syntax

1. AVG()
2. or
3. AVG( [ALL|DISTINCT] expression )

Example:

1. SELECT AVG(COST)
2. FROM PRODUCT_MAST;

Output:

67.00

4. MAX Function

MAX function is used to find the maximum value of a certain column. This function
determines the largest value of all selected values of a column.

Syntax

1. MAX()
2. or
3. MAX( [ALL|DISTINCT] expression )

Example:

1. SELECT MAX(RATE)
2. FROM PRODUCT_MAST;
30

5. MIN Function

MIN function is used to find the minimum value of a certain column. This function
determines the smallest value of all selected values of a column.
Syntax

1. MIN()
2. or
3. MIN( [ALL|DISTINCT] expression )

Example:

1. SELECT MIN(RATE)
2. FROM PRODUCT_MAST;

Output:

10

NULL Values:
In SQL there may be some records in a table that do not have values or data for every field
and those fields are termed as a NULL value.

NULL values could be possible because at the time of data entry information is not available.
So SQL supports a special value known as NULL which is used to represent the values of
attributes that may be unknown or not apply to a tuple.
Importance of NULL Value
It is important to understand that a NULL value differs from a zero value.
A NULL value is used to represent a missing value, but it usually has one of three different
interpretations:
The value unknown (value exists but is not known)
Value not available (exists but is purposely withheld)
Attribute not applicable (undefined for this tuple)
It is often not possible to determine which of the meanings is intended. Hence, SQL does not
distinguish between the different meanings of NULL.
Principles of NULL values
Setting a NULL value is appropriate when the actual value is unknown, or when a value is
not meaningful.
A NULL value is not equivalent to a value of ZERO if the data type is a number and is not
equivalent to spaces if the data type is a character.
A NULL value can be inserted into columns of any data type.
A NULL value will evaluate NULL in any expression.
A trigger is a procedure which is automatically invoked by the DBMS in
response to changes to the database, and is specified by the database
administrator (DBA). A database with a set of associated triggers is
generally called an active database.

Parts of trigger
A triggers description contains three parts, which are as follows −
 Event − An event is a change to the database which activates
the trigger.
 Condition − A query that is run when the trigger is activated
is called as a condition.
 Action −A procedure which is executed when the trigger is
activated and its condition is true.
Use of trigger
Triggers may be used for any of the following reasons −
 To implement any complex business rule, that cannot be
implemented using integrity constraints.
 Triggers will be used to audit the process. For example, to
keep track of changes made to a table.
 Trigger is used to perform automatic action when another
concerned action takes place.
Types of triggers
The different types of triggers are explained below −
 Statement level trigger − It is fired only once for DML
statement irrespective of number of rows affected by
statement. Statement-level triggers are the default type of
trigger.
 Before-triggers − At the time of defining a trigger we can
specify whether the trigger is to be fired before a command
like INSERT, DELETE, or UPDATE is executed or after the
command is executed. Before triggers are automatically used
to check the validity of data before the action is performed.
For instance, we can use before trigger to prevent deletion of
rows if deletion should not be allowed in a given case.
 After-triggers − It is used after the triggering action is
completed. For example, if the trigger is associated with the
INSERT command then it is fired after the row is inserted into
the table.
 Row-level triggers − It is fired for each row that is affected
by DML command. For example, if an UPDATE command
updates 150 rows then a row-level trigger is fired 150 times
whereas a statement-level trigger is fired only for once.
Create database trigger
To create a database trigger, we use the CREATE TRIGGER command. The
details to be given at the time of creating a trigger are as follows −
 Name of the trigger.
 Table to be associated with.
 When trigger is to be fired: before or after.
 Command that invokes the trigger- UPDATE, DELETE, or INSERT.
 Whether row-level triggers or not.
 Condition to filter rows.
PL/SQL block is to be executed when trigger is fired.

The syntax to create database trigger is as follows −
CREATE [OR REPLACE] TRIGGER triggername
{BEFORE|AFTER}
{DELETE|INSERT|UPDATE[OF COLUMNS]} ON table
[FOR EACH ROW {WHEN condition]]
[REFERENCE [OLD AS old] [NEW AS new]]
BEGIN
PL/SQL BLOCK
END.

Problems caused redundancy:


Data redundancy means the occurrence of duplicate copies of similar data. It is done
intentionally to keep the same piece of data at different places, or it occurs accidentally.

What is Data redundancy in the database management system?


In DBMS, when the same data is stored in different tables, it causes data redundancy.

Sometimes, it is done on purpose for recovery or backup of data, faster access of data, or
updating data easily. Redundant data costs extra money, demands higher storage capacity,
and requires extra effort to keep all the files up to date.

Sometimes, unintentional duplicity of data causes a problem for the database to work
properly, or it may become harder for the end user to access data. Redundant data
unnecessarily occupy space in the database to save identical copies, which leads to space
constraints, which is one of the major problems.

Let us understand redundancy in DBMS properly with the help of an example.

Student_id Name Course Session Fee Department


101 Devi B. Tech 2022 90,000 CS
102 Sona B. Tech 2022 90,000 CS
103 Varun B. Tech 2022 90,000 CS
104 Satish B. Tech 2022 90,000 CS
105 Amisha B. Tech 2022 90,000 CS
In the above example, there is a "Student" table that contains data such as "Student_id",
"Name", "Course", "Session", "Fee", and "Department". As you can see, some data is
repeated in the table, which causes redundancy.

Problems that are caused due to redundancy in the database


Redundancy in DBMS gives rise to anomalies, and we will study it further. In a database
management system, the problems that occur while working on data include inserting,
deleting, and updating data in the database.

We will understand these anomalies with the help of the following student table:

student_id student_name student_age dept_id dept_name dept_head


1 Shiva 19 104 Information Technology Jaspreet Kaur
2 Khushi 18 102 Electronics Avni Singh
3 Harsh 19 104 Information Technology Jaspreet Kaur
1. Insertion Anomaly:
Insertion anomaly arises when you are trying to insert some data into the database, but you
are not able to insert it.

Example: If you want to add the details of the student in the above table, then you must know
the details of the department; otherwise, you will not be able to add the details because
student details are dependent on department details.

2. Deletion Anomaly:
Deletion anomaly arises when you delete some data from the database, but some unrelated
data is also deleted; that is, there will be a loss of data due to deletion anomaly.

Example: If we want to delete the student detail, which has student_id 2, we will also lose the
unrelated data, i.e., department_id 102, from the above table.
3. Updating Anomaly:
An update anomaly arises when you update some data in the database, but the data is partially
updated, which causes data inconsistency.

Example: If we want to update the details of dept_head from Jaspreet Kaur to Ankit Goyal
for Dept_id 104, then we have to update it everywhere else; otherwise, the data will get
partially updated, which causes data inconsistency.

Advantages of data redundancy in DBMS


Provides Data Security: Data redundancy can enhance data security as it is difficult for cyber
attackers to attack data that are in different locations.
Provides Data Reliability: Reliable data improves accuracy because organizations can check
and confirm whether data is correct.
Create Data Backup: Data redundancy helps in backing up the data.
Disadvantages of data redundancy in DBMS
Data corruption: Redundant data leads to high chances of data corruption.
Wastage of storage: Redundant data requires more space, leading to a need for more storage
space.
High cost: Large storage is required to store and maintain redundant data, which is costly.
How to reduce data redundancy in DBMS
We can reduce data redundancy using the following methods:

Database Normalization: We can normalize the data using the normalization method. In this
method, the data is broken down into pieces, which means a large table is divided into two or
more small tables to remove redundancy. Normalization removes insert anomaly, update
anomaly, and delete anomaly.
Deleting Unused Data: It is important to remove redundant data from the database as it
generates data redundancy in the DBMS. It is a good practice to remove unwanted data to
reduce redundancy.
Master Data: The data administrator shares master data across multiple systems. Although it
does not remove data redundancy, but it updates the redundant data whenever the data is
changed.
Conclusion:
You have read this article about Data Redundancy in Database Management Systems. You
have understood that data redundancy refers to the repetition of similar data, which may be
done intentionally or it may be accidentally.
You have studied the problems caused by data redundancy, such as delete anomaly, insert
anomaly, and update anomaly.
You have studied the advantages and disadvantages of data redundancy in DBMS.
You have studied some of the methods which reduce data redundancy in DBMS

Relational Decomposition
o When a relation in the relational model is not in appropriate normal
form then the decomposition of a relation is required.
o In a database, it breaks the table into multiple tables.
o If the relation has no proper decomposition, then it may lead to
problems like loss of information.
o Decomposition is used to eliminate some of the problems of bad
design like anomalies, inconsistencies, and redundancy.

Types of Decomposition

Lossless Decomposition

o If the information is not lost from the relation that is decomposed,


then the decomposition will be lossless.
o The lossless decomposition guarantees that the join of relations will
result in the same relation as it was decomposed.
o The relation is said to be lossless decomposition if natural joins of all
the decomposition give the original relation.

Example:
EMPLOYEE_DEPARTMENT table:

EMP_I EMP_NAM EMP_AG EMP_CIT DEPT_I DEPT_NAM


D E E Y D E

22 Denim 28 Mumbai 827 Sales

33 Alina 25 Delhi 438 Marketing

46 Stephan 30 Bangalore 869 Finance

52 Katherine 36 Mumbai 575 Production

60 Jack 40 Noida 678 Testing

The above relation is decomposed into two relations EMPLOYEE and


DEPARTMENT

EMPLOYEE table:

EMP_ID EMP_NAME EMP_AGE EMP_CITY

22 Denim 28 Mumbai

33 Alina 25 Delhi

46 Stephan 30 Bangalore

52 Katherine 36 Mumbai

60 Jack 40 Noida

DEPARTMENT table

DEPT_ID EMP_ID DEPT_NAME

827 22 Sales

438 33 Marketing

869 46 Finance

575 52 Production

678 60 Testing
Now, when these two relations are joined on the common column
"EMP_ID", then the resultant relation will look like:

Employee ⋈ Department

EMP_I EMP_NAM EMP_AG EMP_CIT DEPT_I DEPT_NAM


D E E Y D E

22 Denim 28 Mumbai 827 Sales

33 Alina 25 Delhi 438 Marketing

46 Stephan 30 Bangalore 869 Finance

52 Katherine 36 Mumbai 575 Production

60 Jack 40 Noida 678 Testing

Hence, the decomposition is Lossless join decomposition.

Dependency Preserving

o It is an important constraint of the database.


o In the dependency preservation, at least one decomposed table
must satisfy every dependency.
o If a relation R is decomposed into relation R1 and R2, then the
dependencies of R either must be a part of R1 or R2 or must be
derivable from the combination of functional dependencies of R1
and R2.
o For example, suppose there is a relation R (A, B, C, D) with
functional dependency set (A->BC). The relational R is decomposed
into R1(ABC) and R2(AD) which is dependency preserving because
FD A->BC is a part of relation R1(ABC).

Issues of decomposition in DBMS?


There are many problems regarding the decomposition in
DBMS mentioned below:
 Redundant Storage
Many instances where the same information gets stored in a
single place can confuse the programmers. It will take lots of
space in the system.
 Insertion Anomalies

It isn’t essential for storing important details unless some


kind of information is stored in a consistent manner.
 Deletion Anomalies

It isn’t possible to delete some details without eliminating


any sort of information.
Functional Dependency
The functional dependency is a relationship that exists between two
attributes. It typically exists between the primary key and non-key
attribute within a table.

1. X → Y

The left side of FD is known as a determinant, the right side of the


production is known as a dependent.

For example:

Assume we have an employee table with attributes: Emp_Id, Emp_Name,


Emp_Address.

Here Emp_Id attribute can uniquely identify the Emp_Name attribute of


employee table because if we know the Emp_Id, we can tell that employee
name associated with it.

Functional dependency can be written as:

1. Emp_Id → Emp_Name

We can say that Emp_Name is functionally dependent on Emp_Id.

Types of Functional dependency


1. Trivial functional dependency

o A → B has trivial functional dependency if B is a subset of A.


o The following dependencies are also trivial like: A → A, B → B

Example:

1. Consider a table with two columns Employee_Id and Employee_Nam


e.
2. {Employee_id, Employee_Name} → Employee_Id is a trivial functional d
ependency as
3. Employee_Id is a subset of {Employee_Id, Employee_Name}.
4. Also, Employee_Id → Employee_Id and Employee_Name → Employee_N
ame are trivial dependencies too.

2. Non-trivial functional dependency

o A → B has a non-trivial functional dependency if B is not a subset of A.


o When A intersection B is NULL, then A → B is called as complete non-
trivial.

Example:

1. ID → Name,
2. Name → DOB
Inference Rule (IR):
o The Armstrong's axioms are the basic inference rule.
o Armstrong's axioms are used to conclude functional dependencies on a
relational database.
o The inference rule is a type of assertion. It can apply to a set of
FD(functional dependency) to derive other FD.
o Using the inference rule, we can derive additional functional dependency
from the initial set.

The Functional dependency has 6 types of inference rule:

1. Reflexive Rule (IR1)


In the reflexive rule, if Y is a subset of X, then X determines Y.

1. If X ⊇ Y then X → Y

Example:

1. X = {a, b, c, d, e}
2. Y = {a, b, c}

2. Augmentation Rule (IR2)


The augmentation is also called as a partial dependency. In augmentation,
if X determines Y, then XZ determines YZ for any Z.

PlayNext

Unmute

Current Time 0:00

Duration 18:10

Loaded: 0.37%
Â

Fullscreen
Backward Skip 10sPlay VideoForward Skip 10s

1. If X → Y then XZ → YZ

Example:

1. For R(ABCD), if A → B then AC → BC

3. Transitive Rule (IR3)


In the transitive rule, if X determines Y and Y determine Z, then X must
also determine Z.

1. If X → Y and Y → Z then X → Z

4. Union Rule (IR4)


Union rule says, if X determines Y and X determines Z, then X must also
determine Y and Z.

1. If X → Y and X → Z then X → YZ

Proof:

1. X → Y (given)
2. X → Z (given)
3. X → XY (using IR2 on 1 by augmentation with X. Where XX = X)
4. XY → YZ (using IR2 on 2 by augmentation with Y)
5. X → YZ (using IR3 on 3 and 4)

5. Decomposition Rule (IR5)


Decomposition rule is also known as project rule. It is the reverse of union
rule.

This Rule says, if X determines Y and Z, then X determines Y and X


determines Z separately.

1. If X → YZ then X → Y and X → Z

Proof:

1. X → YZ (given)
2. YZ → Y (using IR 1 Rule)
3. X → Y (using IR3 on 1 and 2)
6. Pseudo transitive Rule (IR6)
In Pseudo transitive Rule, if X determines Y and YZ determines W, then XZ
determines W.

1. If X → Y and YZ → W then XZ → W

Proof:

1.X→Y(given)
2.WY→Z (given)
3.WX→WY(using IR2 on 1 by augmenting with W)
4. WX → Z (using IR3 on 3 and 2)

Normalization
A large database defined as a single relation may result in data
duplication. This repetition of data may result in:

o Making relations very large.


o It isn't easy to maintain and update data as it would involve searching
many records in relation.
o Wastage and poor utilization of disk space and resources.
o The likelihood of errors and inconsistencies increases.

So to handle these problems, we should analyze and decompose the


relations with redundant data into smaller, simpler, and well-structured
relations that are satisfy desirable properties. Normalization is a process
of decomposing the relations into relations with fewer attributes.

What is Normalization?
o Normalization is the process of organizing the data in the database.
o Normalization is used to minimize the redundancy from a relation or set of
relations. It is also used to eliminate undesirable characteristics like
Insertion, Update, and Deletion Anomalies.
o Normalization divides the larger table into smaller and links them using
relationships.
o The normal form is used to reduce redundancy from the database table.

Why do we need Normalization?


The main reason for normalizing the relations is removing these
anomalies. Failure to eliminate anomalies leads to data redundancy and
can cause data integrity and other problems as the database grows.
Normalization consists of a series of guidelines that helps to guide you in
creating a good database structure.

Data modification anomalies can be categorized into three types:

o Insertion Anomaly: Insertion Anomaly refers to when one cannot insert a


new tuple into a relationship due to lack of data.
o Deletion Anomaly: The delete anomaly refers to the situation where the
deletion of data results in the unintended loss of some other important
data.
o Updatation Anomaly: The update anomaly is when an update of a single
data value requires multiple rows of data to be updated.

Types of Normal Forms:


Normalization works through a series of stages called Normal forms. The
normal forms apply to individual relations. The relation is said to be in
particular normal form if it satisfies constraints.

Following are the various types of Normal forms:

Normal Description
Form

1NF A relation is in 1NF if it contains an atomic value.


2NF A relation will be in 2NF if it is in 1NF and all non-key attributes are
fully functional dependent on the primary key.

3NF A relation will be in 3NF if it is in 2NF and no transition


dependency exists.

BCNF A stronger definition of 3NF is known as Boyce Codd's normal


form.

4NF A relation will be in 4NF if it is in Boyce Codd's normal form and


has no multi-valued dependency.

5NF A relation is in 5NF. If it is in 4NF and does not contain any join
dependency, joining should be lossless.

Advantages of Normalization
o Normalization helps to minimize data redundancy.
o Greater overall database organization.
o Data consistency within the database.
o Much more flexible database design.
o Enforces the concept of relational integrity.

Disadvantages of Normalization
o You cannot start building the database before knowing what the user
needs.
o The performance degrades when normalizing the relations to higher
normal forms, i.e., 4NF, 5NF.
o It is very time-consuming and difficult to normalize relations of a higher
degree.
o Careless decomposition may lead to a bad database design, leading to
serious problems.
First Normal Form (1NF)
o A relation will be 1NF if it contains an atomic value.
o It states that an attribute of a table cannot hold multiple values. It must
hold only single-valued attribute.
o First normal form disallows the multi-valued attribute, composite attribute,
and their combinations.

Example: Relation EMPLOYEE is not in 1NF because of multi-valued


attribute EMP_PHONE.

EMPLOYEE table:

EMP_ID EMP_NAME EMP_PHONE EMP_STATE

14 John 7272826385, UP
9064738238

20 Harry 8574783832 Bihar

12 Sam 7390372389, Punjab


8589830302

The decomposition of the EMPLOYEE table into 1NF has been shown
below:

EMP_ID EMP_NAME EMP_PHONE EMP_STATE

14 John 7272826385 UP

14 John 9064738238 UP

20 Harry 8574783832 Bihar

12 Sam 7390372389 Punjab

12 Sam 8589830302 Punjab


Second Normal Form (2NF)
o In the 2NF, relational must be in 1NF.
o In the second normal form, all non-key attributes are fully functional
dependent on the primary key

Example: Let's assume, a school can store the data of teachers and the
subjects they teach. In a school, a teacher can teach more than one
subject.

TEACHER table

TEACHER_ID SUBJECT TEACHER_AGE

25 Chemistry 30

25 Biology 30

47 English 35

83 Math 38

83 Computer 38

In the given table, non-prime attribute TEACHER_AGE is dependent on


TEACHER_ID which is a proper subset of a candidate key. That's why it
violates the rule for 2NF.

To convert the given table into 2NF, we decompose it into two tables:

TEACHER_DETAIL table:

TEACHER_ID TEACHER_AGE

25 30

47 35

83 38
TEACHER_SUBJECT table:

TEACHER_ID SUBJECT

25 Chemistry

25 Biology

47 English

83 Math

83 Computer

Third Normal Form (3NF)


o A relation will be in 3NF if it is in 2NF and not contain any transitive partial
dependency.
o 3NF is used to reduce the data duplication. It is also used to achieve the
data integrity.
o If there is no transitive dependency for non-prime attributes, then the
relation must be in third normal form.

A relation is in third normal form if it holds atleast one of the following


conditions for every non-trivial function dependency X → Y.

1. X is a super key.
2. Y is a prime attribute, i.e., each element of Y is part of some candidate
key.

Example:

EMPLOYEE_DETAIL table:

EMP_ID EMP_NAME EMP_ZIP EMP_STATE EMP_CITY

222 Harry 201010 UP Noida

333 Stephan 02228 US Boston


444 Lan 60007 US Chicago

555 Katharine 06389 UK Norwich

666 John 462007 MP Bhopal

Super key in the table above:

1. {EMP_ID}, {EMP_ID, EMP_NAME}, {EMP_ID, EMP_NAME, EMP_


ZIP}....so on

Candidate key: {EMP_ID}

Non-prime attributes: In the given table, all attributes except


EMP_ID are non-prime.

Here, EMP_STATE & EMP_CITY dependent on EMP_ZIP and EMP_ZIP


dependent on EMP_ID. The non-prime attributes (EMP_STATE,
EMP_CITY) transitively dependent on super key(EMP_ID). It violates
the rule of third normal form.

That's why we need to move the EMP_CITY and EMP_STATE to the


new <EMPLOYEE_ZIP> table, with EMP_ZIP as a Primary key.

EMPLOYEE table:

EMP_ID EMP_NAME EMP_ZIP

222 Harry 201010

333 Stephan 02228

444 Lan 60007

555 Katharine 06389

666 John 462007

EMPLOYEE_ZIP table:
EMP_ZIP EMP_STATE EMP_CITY

201010 UP Noida

02228 US Boston

60007 US Chicago

06389 UK Norwich

462007 MP Bhopal

Boyce Codd normal form (BCNF)


o BCNF is the advance version of 3NF. It is stricter than 3NF.
o A table is in BCNF if every functional dependency X → Y, X is the super key
of the table.
o For BCNF, the table should be in 3NF, and for every FD, LHS is super key.

Example: Let's assume there is a company where employees work in


more than one department.

EMPLOYEE table:

EMP_ID EMP_COUNTRY EMP_DEPT DEPT_TYPE EMP_DEPT_NO

264 India Designing D394 283

264 India Testing D394 300

364 UK Stores D283 232

364 UK Developing D283 549

In the above table Functional dependencies are as follows:

1. EMP_ID → EMP_COUNTRY
2. EMP_DEPT → {DEPT_TYPE, EMP_DEPT_NO}

Candidate key: {EMP-ID, EMP-DEPT}

The table is not in BCNF because neither EMP_DEPT nor EMP_ID alone are
keys.

To convert the given table into BCNF, we decompose it into three tables:

EMP_COUNTRY table:

EMP_ID EMP_COUNTRY

264 India

264 India

EMP_DEPT table:

EMP_DEPT DEPT_TYPE EMP_DEPT_NO

Designing D394 283

Testing D394 300

Stores D283 232

Developing D283 549

EMP_DEPT_MAPPING table:

EMP_ID EMP_DEPT

D394 283

D394 300

D283 232
D283 549

Functional dependencies:

1. EMP_ID → EMP_COUNTRY
2. EMP_DEPT → {DEPT_TYPE, EMP_DEPT_NO}

Candidate keys:

For the first table: EMP_ID


For the second table: EMP_DEPT
For the third table: {EMP_ID, EMP_DEPT}

Now, this is in BCNF because left side part of both the functional
dependencies is a key.

Fourth normal form (4NF)


o A relation will be in 4NF if it is in Boyce Codd normal form and has no
multi-valued dependency.
o For a dependency A → B, if for a single value of A, multiple values of B
exists, then the relation will be a multi-valued dependency.

Example
STUDENT

STU_ID COURSE HOBBY

21 Computer Dancing

21 Math Singing

34 Chemistry Dancing

74 Biology Cricket

59 Physics Hockey
The given STUDENT table is in 3NF, but the COURSE and HOBBY are two
independent entity. Hence, there is no relationship between COURSE and
HOBBY.

In the STUDENT relation, a student with STU_ID, 21 contains two


courses, Computer and Math and two hobbies, Dancing and Singing.
So there is a Multi-valued dependency on STU_ID, which leads to
unnecessary repetition of data.

So to make the above table into 4NF, we can decompose it into two
tables:

STUDENT_COURSE

STU_ID COURSE

21 Computer

21 Math

34 Chemistry

74 Biology

59 Physics

STUDENT_HOBBY

STU_ID HOBBY

21 Dancing

21 Singing

34 Dancing

74 Cricket

59 Hockey
Fifth normal form (5NF)
o A relation is in 5NF if it is in 4NF and not contains any join dependency and
joining should be lossless.
o 5NF is satisfied when all the tables are broken into as many tables as
possible in order to avoid redundancy.
o 5NF is also known as Project-join normal form (PJ/NF).

Example

SUBJECT LECTURER SEMESTER

Computer Anshika Semester 1

Computer John Semester 1

Math John Semester 1

Math Akash Semester 2

Chemistry Praveen Semester 1

In the above table, John takes both Computer and Math class for Semester
1 but he doesn't take Math class for Semester 2. In this case, combination
of all these fields required to identify a valid data.

Suppose we add a new Semester as Semester 3 but do not know about


the subject and who will be taking that subject so we leave Lecturer and
Subject as NULL. But all three columns together acts as a primary key, so
we can't leave other two columns blank.

So to make the above table into 5NF, we can decompose it into three
relations P1, P2 & P3:

P1

SEMESTER SUBJECT
Semester 1 Computer

Semester 1 Math

Semester 1 Chemistry

Semester 2 Math

P2

SUBJECT LECTURER

Computer Anshika

Computer John

Math John

Math Akash

Chemistry Praveen

P3

SEMSTER LECTURER

Semester 1 Anshika

Semester 1 John

Semester 1 John

Semester 2 Akash

Semester 1 Praveen

You might also like