What is CTE?
Its Stands for Common Table Expression.
CTE allows you to define temporary result set, that can
be linked immediately with the select, insert, update or
delete statement.
CTE can be used in a view.
A CTE is defined at the start of query and can be
referenced several times in the outer query.
CTE Exists in memory only while query is running. After
the query run, the CTE discarded and it can’t be used
next SQL Query unless we define it again.
when the outer query ends, the lifetime of the CTE will
End.
Syntax:
With Expression_name( Col1,col2)
As
(
CTE Defination
)
Example CTE with Select query
Created table called Student and Creating CTE with name New_CTE
With New_CTE
As
(
Select * from Student where gender ='male'
)
Select * from New_CTE;
Counting the No. of Male Student using CTE
With New_CTE
As
(
Select * from Student where gender ='male'
)
Select Count (*) as Male_student from New_CTE
Showing Male students whose age is above or equal to 17
With New_Stud
As
(
Select * from Student where gender = 'Male')
Select * from New_stud where age>=17;
Using Columns in CTE
You need to define a Unique names for each of the
columns referenced in the Select clause of the CTE
Example
with New_CTE (std_ID, std_name, std_class)
AS
(
Select id, name, standard from student where
gender='female'
)
select std_ID, std_name, std_class from New_CTE;
It is possible to use External Aliases for columns in CTEs.
Example
With New_CTE
as
(
Select count (*) as Total_Gender from Student where
gender= 'female'
)
Select * from New_CTE
Using Insert in CTE
with New_CTE
As
(
Select * from Student
)
Insert New_CTE values (11,'Kavi','male',15,8)
Using Update in CTE
with New_CTE
As
(
Select * from Student
)
Update New_CTE set Gender=’female’ where id=12;
with New_CTE
as (
select * from Student
)
--Update New_CTE set Gender='female' where id=9;
Update New_CTE set Name='Parikshit' where ID= 9 ;
Using Delete in CTE
Syntax:
With Expression_name( Col1,col2)
As
(
CTE Defination
)
Delete Expression_name where Col=value;
with New_CTE
As
(
Select * from Student
)
Delete New_CTE where id= 9
View in CTE
A view is a stored SQL Query that is executed each time
you reference it in another query.
View does not store the result set of a particular query,
But it stores query itself.
Example
Create view MYNewView
As
With New_CTE
As
(
Select * from student where [standard] =12
)
Select * from New_CTE
Calling the view
Select * from MYNewView;
Multiple CTEs Using Single with clause
With New_CTE
As
(
Select * from Student where [standard]=12
),
New_CTE2
As
(
Select * from Student where [standard]=11
)
Select * from New_CTE
Union all
Select * from New_CTE2
CTE Vs Sub query
CTE is created before the Outer Query
Subquery is created after the outer query
Advantages
CTEs are improved Readability
Ease in maintenance of complex queries
For better Performance
Example
Created Emp_Details table
Select * From Emp_Details;
Fetch Employee who earn more than avg. salary of all employees.
Using Sub Query
Select * from Emp_Details where Salary > (Select
Avg(Salary) from Emp_Details)
Using With Clause
With average_salary (avg_sal )
as
(
Select avg(salary) avg_sal from Emp_Details
)
Select * from Emp_Details , average_salary where salary
> avg_sal
Create Sales table
Create table sales(
Store_ID Int,
Store_name varchar(255),
Product Varchar(255),
Quantity int,
Cost int
)
Insert into sales (Store_ID, Store_name, Product,
Quantity,cost) values ( 1,'Apple_originals_1','iPhone 12
pro' ,1, 1000),
( 1,'Apple_originals_1','Macbook pro 13' ,3, 2000),
( 1,'Apple_originals_1','Airpods pro' ,2, 280),
( 2,'Apple_originals_2','iPhone 12 pro' ,2, 1000),
( 3,'Apple_originals_3','iPhone 12 pro' ,2, 1000),
( 3,'Apple_originals_3','Macbook pro 13' ,1, 2000),
(4 ,'Apple_originals_4','Iphone 12 pro' ,2, 1000),
(4,'Apple_originals_4','Macbook 12 pro' ,3, 2000)
Find store who’s sales where better than the average sales across all
stores.
1. Total sales per each store—Total_sales
Select s.store_Id, sum(cost) as total_sales_per_store from sales
s group by s.store_ID;
2. Find the average sales wrt all the store – avg_sales
Select Avg(total_sales_per_store ) as Avg_sales_for_all_store
from (Select s.store_Id, sum(cost) as total_sales_per_store from
sales s group by s.store_ID) ;
)
3. Find the store where total_sales> avg_sales
Using Sub Query
Select * from
( Select s.Store_ID ,sum(Cost) as total_sales_per_store
from sales s group by s.store_ID) total_sales
join (
Select avg( total_sales_per_store ) as
avg_sales_for_all_stores from( select s.store_id, sum(cost)
as total_sales_per_store from sales s Group by s.store_ID)
x) avg_sales
on
total_sales.total_sales_per_store >
avg_sales.avg_sales_for_all_stores;
Using With clause
with Total_sales (store_id, total_Sales_per_store)
as
(select s.Store_ID ,sum(Cost) as total_sales_per_store
from sales s group by s.store_ID),
AVg_Sales ( avg_sales_for_all_store) // 2nd CTE//
as
(Select avg(total_sales_per_store) as
avg_sales_for_all_store from Total_sales)
// outer query//
Select * from Total_sales ts
Join
Avg_sales AV on ts.total_sales_per_store >
av.avg_sales_for_all_store.
Recursive :
A recursive common table expression (CTE) is a CTE that
references itself. The CTE repeatedly executes, returns subsets
of data, until it returns the complete result set.
A recursive CTE is useful in querying hierarchical data such as
organization charts where one employee reports to a manager.
In general, a recursive CTE has three parts:
An initial query that returns the base result set of the CTE. The
initial query is called an anchor member.
A recursive query that references the common table expression,
therefore, it is called the recursive member. The recursive
member is unioned with the anchor member using the UNION
ALL operator.
A termination condition specified in the recursive member that
terminates the execution of the recursive member.
The execution order of a recursive CTE is as follows:
Syntax:
With [Recursive] CTE_name as
(
Select query (NON Recursive query or the base query)
Union ALL
Select query (recursive query using CTE_Name [with a
termination condition]
)
Select * from CTE_name;
Example:
Display number from 1 to 10 without using any in built functions.
With Numbers as
(
Select 1 as n
Union all
Select n+1 from numbers where n <10
)
Select * from numbers;
Find the hierarchy of employees under a given manager ‘Asha’
Created Emp_Info
Create table Emp_info(
Id int Primary Key,
Name Varchar(100),
Manager_Id int,
Salary int,
Designation Varchar(100)
Insert Emp_info ( Id, Name, Manager_id, Salary, Designation) values
(1,’Shripadh’, null,100000, ‘CEO’),
(2,'Satya', 5, 1400, 'Software Engineer'),
(3,'Jia',5 , 500, 'Data Analyst'),
(4,'David',5 , 1800, 'Data Scientist'),
(5,'Michel',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 dev')
With Emp_hierarchy
As
(
Select Id, name, manager_ID, designation, 1 as level from emp_info
where name='Asha'
Union All
Select E.id, E.name,E.manager_Id, E.designation, h.level+1 as Level
from emp_hierarchy h
Join emp_info E on H.id =E.manager_id
)
Select * from emp_hierarchy;
To display Emp_ID, Emp_name,Manager name in a result table
Select h.id as emp_id, h.name as emp_name, E.name as
manager_name, h.level as [Level] from emp_hierarchy h
Join Emp_info E on E.id=h.manager_id
Find the Hierarchy of manager for given employee “David”
With Emp_hierarchy
As
(
Select Id, name, manager_ID, designation, 1 as level from emp_info
where name=’Asha’
Union All
Select E.id, E.name,E.manager_Id, E.designation, h.level+1 as Level
from emp_hierarchy h
Join emp_info E on H. manager_id=E.id
)
Select H2.id as emp_id, H2.name as emp_name, E2.name as
manager_name, h2.Level as Level from emp_hierarchy H2
Join Emp_info E2 on E2.id=H2.manager_id
Order BY In CTE
WITH Sal_OrderBy AS(
SELECT
ROW_NUMBER() OVER (
ORDER BY salary
) row_num,
Emp_ID,
Emp_Name,
salary
FROM
Emp_Details
)
SELECT * FROM Sal_OrderBy WHERE row_num > 2 AND
row_num <=5;
Finding Nth Highest Salary from Emp_Info table
Displaying Max salary from Emp_info table
Select * from Emp_info where salary =( Select max(salary) from
Emp_info)
Finding less than the highest salary
Select * from Emp_info where Salary< (select max( Salary) from
Emp_info) order by salary desc
Finding 2nd highest salary
Select * from Emp_info where Salary= (Select Max(salary) from
Emp_info where Salary< (select max( Salary) from Emp_info))
By using Top Function highest salary
Select top 1 * from Emp_info
1st highest salary
Select top 1 * from (Select top 3 * from Emp_info order by salary
desc ) as sal_order
By using Top Function finding nth highest salary
3rd highest value
Select top 1 * from (Select top 3 * from Emp_info order by salary
desc ) as sal_order order by salary
5th highest value
Here we will change only value in sub query
Select top 1 * from (Select top 5 * from Emp_info order by salary
desc ) as sal_order order by salary
By using CTE find the nth Highest salary
3rd Highest salary
With Salary_CTE
As
( select * , dense_rank() over (order by salary desc) as sal_order from
Emp_info)
Select * from salary_CTE where Sal_order =3
Select * from salary_CTE where Sal_order =5
3rd lowest salary
With Salary_CTE
As
( select * , dense_rank() over (order by salary ) as sal_order from
Emp_info)
Select * from salary_CTE where Sal_order =3
Finding the duplicate rows in a table
Create Table EmpDetail (
ID int identity(1,1),
EmpName varchar(25),
Departmemt varchar(20),
Age int,
Gender char(1),
Salary Bigint
)
Insert into EmpDetail values('James','HR',30,'M',40000)
Insert into EmpDetail values('James','HR',30,'M',40000)
Insert into EmpDetail values('James','HR',30,'M',40000)
Insert into EmpDetail values('John','Finance',32,'M',45000)
Insert into EmpDetail values('Maria','Admin',28,'M',30000)
Insert into EmpDetail values('Maria','Admin',28,'M',30000)
Insert into EmpDetail values('Mark','Account',35,'M',50000)
Select EmpName,Departmemt,Age,Gender,Salary, count(*) from EmpDetail
Group By EmpName,Departmemt,Age,Gender,Salary
Delete from EmpDetail where ID not in (select max(ID) from EmpDetail Group
By EmpName,Departmemt,Age,Gender,Salary)
WITH duprow AS
(Select
EmpName,Departmemt,Age,Gender,Salary ,ROW_NUMBER()OVER(PARTIT
ION BY EmpName,Departmemt,Age,Gender,Salary ORDER BY ID) AS
RowNumber FROM EmpDetail)
--Select * from duprow
DELETE FROM duprow WHERE RowNumber >1
Stored Procedure
A stored proc is group of SQL state. If we have a situation,
where we write the same query over and over again, then we can
save that specific query as stored procedure and call it just by its
name.
Created store procedure with out Parameter
Create Proc GetEMPInfo
As
Begin
Select name,Salary, Designation from Emp_info
End
To execute the store procedure
Name of procedure (GetEMPInfo) and click on execute
option
Exec name of Proc (GetEMPInfo)
Execute name of proc (GetEMPInfo)
Created store procedure with Parameter
Create proc GetEmp_infoByPara
@manager_ID int,
@Designation Varchar(50)
As
Begin
Select Name,salary,manager_ID, designation from Emp_info where
Manager_ID= @manager_ID and Designation= @Designation
End
To execute
Exec GetEmp_infoByPara 7, Manager
Exec GetEmp_infoByPara ( Proc name) @Manager_ID= 7 ,
@Designation= ‘Manager’
To view the Text of stored Procedure
Use System Stored procedure sp_helptext ‘Store procedure
Name’( sp_helptext GetEmp_infoByPara)
Right Click the SP in object explore -> Script Procedure as ->
Create to-> New Query Editor window
To delete the stored Procedure
Drop Proc ‘Store Proc Name’= Drop proc ‘GetEmp_infoByPara’
To Encrypt the Store Procedure
It is not Possible to view the Text of an Encrypted Store Proc
Alter procedure SelectStudent
--With Encryption
As
Begin
Select ID,Name from Student order by Name;
End;
GO
Store Procedure – output Parameters
To create and sp with output parameter, we use keywords out or
output
Created Table
Create table Employees(
ID int ,
Name varchar(50),
Gender varchar(10),
Department_ID int
)
Insert into Employees values(1,'AAAA','Male',1),
(2,’Sam’,’Male’, 1),
(3,’Ram’,’Male’, 3) ,
(4,’sara’,’FeMale’, 3),
(5,’John’,’Male’, 2),
(6,’sana’,’FeMale’, 2),
(7,’Jeams’,’Male’, 1),
(8,’Rob’,’Male’, 2),
(9,’Steve’,’Male’, 1),
(10,’Pam’,’FeMale’, 2)
Create proc SPGetEmployeesCountByGender
@Gender varchar(20), @Employeescount int output
As
Begin
Select @Employeescount=Count(ID) from Employees where
gender=@gender
End
To execute the Stored Procedure with output Parameter
Declare @totalCount int
Exec SPGetEmployeesCountByGender 'Male', @totalCount output
Print @totalCount
If(@totalCount is null)
Print '@totalcount is null'
Else
Print '@totalCount is not null'
Declare @totalCount int
Exec SPGetEmployeesCountByGender @Employeescount
=@totalCount out , @gender='Male'
Print @totalCount
Example for Stored procedure with CTE
Created proc SPCTEexample ( @Emp_Name varchar(20)
as
Begin
With CTEexample (Emp_ID, Emp_Name, Salary)
as
(
Select Emp_ID, Emp_Name, Salary from Emp_Details
)
Select * from CTEexample where Emp_Name=@Emp_Name
END
Exec SPCTEexample 'Suresh'
Temporary Tables
Temporary tables, are very similar to the permanent tables.
Permanent tables get created in the database you specify, and
remain in the database permanently, until you delete (drop)
them.
But temporary tables get created in the TempDB and are
automatically deleted, when they are no longer used.
A local temporary table is available, only for the connection that
has created the table
If you open another query window, and execute the
following query you get an error stating 'Invalid object name
#PersonDetails'.
Different Types of Temporary tables
2 types of Temporary tables
Local Temporary tables and
Global Temporary tables.
Local Temporary tables:
1. To Create a Local Temporary Table
Prefix the Table name with # symbol and it will store the table in
tempDb.
Create Table #PersonDetails(
Id int, Name nvarchar(20)
)
Insert the data into the Temp Table
Insert into #PersonDetails Values(1, 'Mike)
Insert into #PersonDetails Values(2, 'John')
Insert into #PersonDetails Values(3, 'Todd')
Select * from #PersonDetails
2. To check if the local temporary table is created
Temporary tables are created in the TEMPDB object explorer.
The name of the table, is suffixed with lot of underscores and a
random number.
Select name from tempdb..sysobjects
where name like '#PersonDetails%'
3. A local temporary table is available, only for the connection that
has created the table
If you open another query window, and execute the
following query you get an error stating 'Invalid object name
#PersonDetails'.
4. local temporary table is automatically dropped, when the
connection that has created the it, is closed.
5. If the user wants to explicitly drop the temporary table, he can
do so using
DROP TABLE #PersonDetails
6. It is also possible for different connections or another window,
to create a local temporary table with the same name.
For example : create a local temporary table with the same
name #PersonDetails.
To differentiate between, Same local temp tables, sql server
assigns the random number at the end of the temp table
name.
Create table:
Create Table #PersonDetails(
Id int, Name nvarchar(20)
)
Temp Tables in Store Procedure
7. If the temporary table, is created inside the stored procedure, it
get's dropped automatically upon the completion of stored
procedure execution.
It destroys the temporary table immediately after the
completion of the stored procedure execution.
Example
Create Procedure spCreateLocalTempTable
as
Begin
Create Table #PersonDetails(Id int, Name nvarchar(20))
Insert into #PersonDetails Values(1, 'Mike')
Insert into #PersonDetails Values(2, 'John')
Insert into #PersonDetails Values(3, 'Todd')
Select * from #PersonDetails
End
Exec spCreateLocalTempTable
--Select * from #PersonDetails (Give an Error ‘Invalid object name
'#PersonDetails'.’)
To Create a Global Temporary Table:
1. Use prefix the name of the table with 2 pound (##) symbols.
Example
Create Table ##EmployeeDetails(Id int, Name nvarchar(20))
Insert into ##EmployeeDetails Values(1, 'Mike')
Insert into ##EmployeeDetails Values(2, 'John')
Insert into ##EmployeeDetails Values(3, 'Todd')
Global temporary tables are visible to all the connections of the
sql server, and are only destroyed when the last connection
referencing the table is closed.
global temporary table name has to be unique.
In the object explorer, there will be no random numbers
suffixed at the end of the table name.