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

Advance SQL With Rajan Chettri

You can use subquery to fetch columns from a single table, but not from multiple tables. Joins allow you to include columns from multiple tables by correlating rows between two tables based on a common column.

Uploaded by

Manas Badu
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)
90 views47 pages

Advance SQL With Rajan Chettri

You can use subquery to fetch columns from a single table, but not from multiple tables. Joins allow you to include columns from multiple tables by correlating rows between two tables based on a common column.

Uploaded by

Manas Badu
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/ 47

-- When to Use Subquery and When to Use Joins ?

-- Fetching name of countries that speak hindi as of one their language.

use world;

select name from country


where CODE
in
(select countrycode from countrylanguage where language='hindi');

Please Note: the Limitation of Subquery : observe the line no 11 : we are fetching Name column
from Country Table.

If i wish to fetch columns from countrylanguage table and include it in output i can’t do it in
subquery.

Because subquery cannot fetch columns from multiple tables , it can fetch column from single
table only.

This is exactly where Joins are needed, joins allows us to include columns from multiple tables.
Summary: you can correlate rows of 2 tables using both subquery and join but u need join to
display columns from multiple tables as subquery can show column from 1 table only.

Understanding JOINS ( INNER/LEFT/Right/Full/Cross)

File : restaurant.sql
Link:
https://drive.google.com/file/d/1mr3RJY4OXEEqS_s9pXs76mq0Mn7Oz1uo/view?usp=sharing

(please ignore accessories and products table)


Quick Question: if we wish to identify if the 2 person are same in both table which
column we can use as common column ?

Answer: PhoneNo
Task : You are asked to find the Loyal Customers of the Restaurant !

Mathematically ? Intersection
SQL : inner join

Inner join fetches common rows from both table using common columns.

Let us talk about the Syntax:

Select

<columns>

From <Table1> Inner join <Table2>


ON

<Table1.CommonColumn> = <Table2.CommonColumn>;
select
wc.customername as 'walkinCustomer',
oc.customername as 'onlineCustomer',
wc.phoneno as 'walkinContact',
oc.phoneno as 'onlineContact',
ratings

from walkin_customers wc inner join online_customers oc


on
wc.phoneno = oc.phoneno;

Note: please check walkinContact & Online Contact Column are we getting only common
contacts from both Table ?

-- Left Join : Left Join Fetches ALL Rows from Left Table and ONly Matching Rows from
Right Table
select
wc.customername as 'walkinCustomer',
oc.customername as 'onlineCustomer',
wc.phoneno as 'walkinContact',
oc.phoneno as 'onlineContact',
ratings

from walkin_customers wc left join online_customers oc


on
wc.phoneno = oc.phoneno;
select
wc.customername as 'walkinCustomer',
oc.customername as 'onlineCustomer',
wc.phoneno as 'walkinContact',
oc.phoneno as 'onlineContact',
ratings

from walkin_customers wc left join online_customers oc


on
wc.phoneno = oc.phoneno where oc.phoneno is null;

-- Right Join : All Rows from Right Table and Only Matching Rows from Left Table .
select
wc.customername as 'walkinCustomer',
oc.customername as 'onlineCustomer',
wc.phoneno as 'walkinContact',
oc.phoneno as 'onlineContact',
ratings

from walkin_customers wc right join online_customers oc


on
wc.phoneno = oc.phoneno;

-- Full Join : Full JOin Fetches ALL ROWS FROM BOTH TABLES.
-- Full Join is implemented By Merging Output of Left and Right Join using union Keyword.

Merge Left Join with Right Join ! using UNION KEYWORD.

We will also answer interview question difference between union vs union All.

-- union concats or merges the output of 2 or more select statements.

-- here is an example

select 'jeep' as car


union
select 'harrier'
union
select 'xuv700';
select 'jeep' as car
union
select 'harrier'
union
select 'harrier'
union
select 'harrier'
union
select 'xuv700';
select 'jeep' as car
union
select 'harrier'
union all
select 'harrier'
union all
select 'harrier'
union all
select 'xuv700';

Summary : union eliminates duplicate rows where as union all retains duplicate rows.
Implementing Full Join :

select
wc.customername as 'walkinCustomer',
oc.customername as 'onlineCustomer',
wc.phoneno as 'walkinContact',
oc.phoneno as 'onlineContact',
ratings

from walkin_customers wc left join online_customers oc


on
wc.phoneno = oc.phoneno

union

select
wc.customername as 'walkinCustomer',
oc.customername as 'onlineCustomer',
wc.phoneno as 'walkinContact',
oc.phoneno as 'onlineContact',
ratings

from walkin_customers wc right join online_customers oc


on
wc.phoneno = oc.phoneno;
-- Cross Join : Cross join is also called Cartesian Product , in Cross Join each row of one table
-- is multiple with all the rows of Other Table.

select * from walkin_customers cross join online_customers;


Task :

You are asked to Calculate New Prices when Each Product is Sold with All the other
Accessories
select productid , pname , pprice, aname, aprice , (pprice+aprice) as 'ComboPrice' from
products cross join accessories;

Ranking Functions

Create database rankingdb;

Use rankingdb;

create table employee(emp_id int(5),Name varchar(20),Phone varchar(20),Address


varchar(20),salary int(10),projects_comp int (5));

insert into `employee`(`emp_id`,`Name`,`phone`,`Address`,`salary`,`projects_comp`) values


(103,'Atelie',8059912345,'New York',137000,21),
(100,'Harris',9546248620,'California',200000,25),
(1002,'Murphy',8568612304,'Washington',120000,14),
(102,'Maria',8568705304,'Washington',125000,24),
(105,'Max',8708612304,'Chicago',132000,25),
(107,'Martin',7456612304,' Los Angeles',130000,15),
(106,'Thomas',7456632504,'Austin',135000,17),
(108,'Jessica',7866632504,'Boston',140000,16),
(109,'James',8479632504,'Chicago',115000,14),
(110,'John',9516632504,'New York',137000,15),
(111,'Jackie',7421032504,'Boston',138000,27),
(101,'Janet',7050032504,'Houston',139000,19);
select * ,

row_number() over ( order by projects_comp desc ) as 'empRank'

from employee;
select * ,

rank() over ( order by projects_comp desc ) as 'empRank'

from employee;
select * ,

dense_rank() over ( order by projects_comp desc ) as 'empRank'

from employee;

CREATE TABLE IF NOT EXISTS sales1(


sales_employee VARCHAR(50) NOT NULL,
fiscal_year INT NOT NULL,
sale DECIMAL(14,2) NOT NULL,
PRIMARY KEY(sales_employee,fiscal_year)
);
INSERT INTO sales1(sales_employee,fiscal_year,sale)
VALUES('Bob',2016,100),
('Bob',2017,150),
('Bob',2018,200),
('Alice',2016,150),
('Alice',2017,100),
('Alice',2018,200),
('John',2016,200),
('John',2017,150),
('John',2018,250);
select * from sales1;

Task : you are asked to Rank Each Employee for Each Fiscal year based on sale in Desc!!
select * ,
dense_rank() over(order by sale desc) as 'empRank'
from sales1;

select * ,
dense_rank() over(partition by fiscal_year order by sale desc) as 'empRank'
from sales1;

Partitioning Affects RANKING!!!


with salesNew
as
(

select * ,
dense_rank() over(partition by fiscal_year order by sale desc) as 'empRank'
from sales1
)
select * from salesNew where emprank=1;

select name,countrycode,population ,
dense_rank() over (partition by countrycode order by population desc) as cityRank
from city where countrycode in ('chn','idn','aus');
with topCities
as
(
select name,countrycode,population ,
dense_rank() over (partition by countrycode order by population desc) as cityRank
from city where countrycode in ('chn','idn','aus')
)
select * from topCities where cityRank=1;
-- you are asked to find the name Most Populated CITY from CHINA , INDONESIA ,
AUSTRALIA

-- Approach , generate a new CityRank column based on population in descending Order


-- make sure we partition the data by CountryCode so that the Rank resets for Each Country
-- USe CTE to filter the Data where CityRank matches with 1

Employees.sql

https://drive.google.com/file/d/1rDTvxl4eTMj_ovZKP9w3Bh_u3A19tasb/view?usp=sharing
Task : You are Asked to Prepare a Report which show

EmployeeNo | Current Salary | Next Salary | Increment Amount


select emp_no,salary,

lead(salary,1) over ( order by emp_no asc) as 'NextSalary'


from salaries;

select emp_no,salary,

lead(salary,1) over ( partition by emp_no order by emp_no asc) as 'NextSalary'


from salaries;
with SalaryHistory
as
(select emp_no,salary,

lead(salary,1) over ( partition by emp_no order by emp_no asc) as 'NextSalary'


from salaries
)
select * , (NextSalary-Salary) as 'IncrementAmount' from SalaryHistory;

-- the Script that we just RAN created a Database in our system named 'world'

-- check database

show databases; -- press ctrl+enter to run the query

-- Next we will select Database world using 'use' command

use world;
-- now we will check Tables Inside World Database

show tables;

-- To Display Table Content use 'select' Statement


-- Syntax:
-- select * from <TableName>;

select * from city;

-- * in select statement means ALL Columns ( Fetch All Columns)

-- this is how we show choice of columns

select name,district,population from city;

-- Can we DO maths with Columns ? YES

select name,district,population , population + 1 as 'New Population' from city;

-- Filtering Records using 'where'


-- Syntax:
-- select * from <tableName> where <Condition>;

select * from city where ID = 29;

select * from city where population < 800;

-- Here are the indian cities

select * from city where countrycode ='ind';

-- using Logical Operators i.e AND , OR , NOT

-- using AND

select * from city where district='punjab' and countrycode='ind';

-- another example

select * from city where id>=5 and id<=12;


-- using OR

select * from city where id=5 or id=15 or id=55;


select * from city where countrycode='afg' or countrycode='idn';

-- using NOT

select * from city where not (countrycode='afg' or countrycode='idn');

select * from city where not (id>=5 and id<=12);

-- SQL Best Practices

-- Range Operator i.e Between and Not Between (this is used to capture data in Range)

select * from city where id between 6 and 12;

select * from city where id Not between 6 and 12;

-- in keyword : this is used to compare a column with multiple values.

select * from city where id in (2,6,8);

select * from city where countrycode in ('afg','nld','idn');

-- excluding using not

select * from city where countrycode not in ('afg','nld','idn');

-- Activity

select * from countrylanguage;

-- Task : Find the details of Languages which are spoken by 80 to 90 percent of People and are
Official
-- Languages ONLY.

select * from countrylanguage where percentage between 80 and 90 and IsOfficial = 'T';

-- between is delhi to chennai


-- in is delhi or chennai

-- is keyword: this is used to compare a column with null;

select name,indepyear from country;

select name,indepyear from country where indepyear is null;

-- SORTING using 'order by'


-- What is the Syntax:
-- select * from <TableName> order by <ColumnName> <Order>

select * from city order by population desc;

select * from countrylanguage where countrycode='idn' order by percentage desc;

-- using limit Keyword


-- u can use limit keyword to fetch TOP N Rows from your OUTPUT

select * from countrylanguage where countrycode='idn' order by percentage desc limit 3;

-- Aggregate Functions : agg. functions help us find statistical Facts from Data.

select
max(population) as 'Max Population',
min(population) as 'Min Population',
sum(population) as 'Sum Population',
avg(population) as 'Avg Population',
count(population) as 'Count Population'
from city;
-- count: function returns count of values in column excluding Nulls.

-- finding count of rows

select count(*) from city;

-- eleminating duplicates using distinct keyword

select continent from country;

select distinct continent from country;

-- finding the count of unique values

select count(distinct continent) from country;

-- Rajdeep's Doubt
-- difference in union vs union all

-- union is used to combine or merge output or result of 2 or more select queries

select countrycode , language from countrylanguage where countrycode='idn'

union

select countrycode , language from countrylanguage where countrycode='afg';

-- difference in union vs union all

select 'jeep' as car


union
select 'harrier'
union
select 'harrier'
union
select 'harrier'
union
select 'xuv700';

select 'jeep' as car


union
select 'harrier'
union all
select 'harrier'
union all
select 'harrier'
union all
select 'xuv700';

-- Grouping

select name,continent from country;

-- if i group records using Continent , how many groups will be formed ?


-- if i COUNT no of ROWS in Each GROUP what will i GET ? CountryCOUNT

select continent, count(continent) from country group by Continent;

-- here is another example

select continent, surfaceArea from country;

-- What is the Total SurfaceArea of Each Continent;

select continent, sum(surfacearea) from country group by continent;

-- filter using having in .aggregated Column


select continent, sum(surfacearea) from country group by continent
having sum(surfaceArea) > '24214470.00';

-- Pattern Based Search using like keyword

-- find cities whose name starts with 'tom'


select * from city where name like 'tom%';

-- find cities whose name ends with 'ning'


select * from city where name like '%ning';

-- find cities whose name contains 'jian'


select * from city where name like '%jian%';
-- find cities whose name contains exactly 5 characters

select * from city where name like '_____';

-- 1 underscore means 1 character in our case 5 underscores

-- what does the below expression means

select * from city where name like '_U___';

-- Nested Queries

-- suppose i wish to find the city detail with largest population

-- case 1

select max(population) from city;


select * from city where population =10500000;

-- case 2

select * from city where population = (select max(population) from city);

select * from country;

-- Step 1 : we will fetch CountryCodes from Countrylanguage Table where language matches
with
-- ‘Hindi’;

-- Step 2: we will then compare Countrycodes from countrylanguage with Code


-- from Country Table to find the Name of Countries.

select name from country


where

CODE IN
(
select countrycode from countrylanguage where language='hindi'
);

use employees;

select * from titles;

-- First we will fetch the emp_no from titles where title matches with ‘senior Engineer’
-- Then we will compare emp_no from titles with emp_no from employees to find the
-- First_name and last_name;

select first_name, last_name from employees where


emp_no
in
(
select emp_no from titles where title='Senior Engineer'
);

use restaurants_db;

select * from online_customers;

-- Select
-- <columns>
-- From <Table1> Inner join <Table2>
-- ON
-- <Table1.CommonColumn> = <Table2.CommonColumn>;
select
wc.customername as 'walkinCustomer',
oc.customername as 'onlineCustomer',
wc.phoneno as 'walkinContact',
oc.phoneno as 'onlineContact',
ratings

from walkin_customers wc inner join online_customers oc


on
wc.phoneno = oc.phoneno;

-- Left Join : Left Join Fetches ALL Rows from Left Table and ONly The Matching Rows from
Right Table

select
wc.customername as 'walkinCustomer',
oc.customername as 'onlineCustomer',
wc.phoneno as 'walkinContact',
oc.phoneno as 'onlineContact',
ratings

from walkin_customers wc left join online_customers oc


on
wc.phoneno = oc.phoneno;

select
wc.customername as 'walkinCustomer',
oc.customername as 'onlineCustomer',
wc.phoneno as 'walkinContact',
oc.phoneno as 'onlineContact',
ratings

from walkin_customers wc left join online_customers oc


on
wc.phoneno = oc.phoneno where oc.phoneno is null;

-- Right Join : All Rows from Right Table and Only Matching Rows from Left Table .

select
wc.customername as 'walkinCustomer',
oc.customername as 'onlineCustomer',
wc.phoneno as 'walkinContact',
oc.phoneno as 'onlineContact',
ratings

from walkin_customers wc right join online_customers oc


on
wc.phoneno = oc.phoneno;

-- Full Join : Full JOin Fetches ALL ROWS FROM BOTH TABLES.
-- Full Join is implemented By Merging Output of Left and Right Join using union Keyword.

-- union concats or merges the output of 2 or more select statements.

-- here is an example

select 'jeep' as car


union
select 'harrier'
union all
select 'harrier'
union all
select 'harrier'
union all
select 'xuv700';
select
wc.customername as 'walkinCustomer',
oc.customername as 'onlineCustomer',
wc.phoneno as 'walkinContact',
oc.phoneno as 'onlineContact',
ratings

from walkin_customers wc left join online_customers oc


on
wc.phoneno = oc.phoneno

union

select
wc.customername as 'walkinCustomer',
oc.customername as 'onlineCustomer',
wc.phoneno as 'walkinContact',
oc.phoneno as 'onlineContact',
ratings

from walkin_customers wc right join online_customers oc


on
wc.phoneno = oc.phoneno;

-- Cross Join : Cross join is also called Cartesian Product , in Cross Join each row of one table
-- is multiple with all the rows of Other Table.

select * from walkin_customers cross join online_customers;

-- Diwali is near , the Electronic store owner has decided to launch combo Offers on Products
select * from products;
select * from accessories;

select productid , pname , pprice, aname, aprice , (pprice+aprice) as 'ComboPrice' from


products cross join accessories;

use rankingdb;
select * from employee;

-- There are 3 Primary Ranking Functions

-- 1 Row_number()
-- 2 Rank()
-- 3 Dense_Rank()

select * ,

row_number() over ( order by projects_comp desc ) as 'empRank'

from employee;

select * ,

rank() over ( order by projects_comp desc ) as 'empRank'

from employee;

-- what is the pattern : rank: 1 2 2 2 5 6 7 7 9

-- use case : DREAM 11

-- if 2 people got the same rank they will split the prize money
-- 3rd one will get the 3rd RANK so he gets prize money for the 3rd Rank only.
-- mohan 1 50rs
-- ramesh 1 50rs
-- suresh 3 10rs

select * ,

dense_rank() over ( order by projects_comp desc ) as 'empRank'

from employee;

-- Ranking with Partioning

select * from sales1;

select * ,
dense_rank() over(partition by fiscal_year order by sale desc) as 'empRank'
from sales1;

-- CTE i.e Common Table Expression


-- CTE is Not more a Descent Query Simplification TECHNIQUE in SQL

-- Syntax :

-- with TempTable
-- as
-- ( <QueryGoes Here> )
-- select * from TempTable;

with salesNew
as
(

select * ,
dense_rank() over(partition by fiscal_year order by sale desc) as 'empRank'
from sales1
)
select * from salesNew;

-- what is the benefit of CTE here ?

select * ,
dense_rank() over(partition by fiscal_year order by sale desc) as 'empRank'
from sales1 where empRank=1;

with salesNew
as
(

select * ,
dense_rank() over(partition by fiscal_year order by sale desc) as 'empRank'
from sales1
)
select * from salesNew where emprank=1;

USE world;

-- you are asked to find the name Most Populated CITY from CHINA , INDONESIA ,
AUSTRALIA

-- Approach , generate a new CityRank column based on population in descending Order


-- make sure we partition the data by CountryCode so that the Rank resets for Each Country
-- USe CTE to filter the Data where CityRank matches with 1

select name,countrycode,population ,
dense_rank() over (partition by countrycode order by population desc) as cityRank
from city where countrycode in ('chn','idn','aus');

-- use CTE to filter rows


with topCities
as
(
select name,countrycode,population ,
dense_rank() over (partition by countrycode order by population desc) as cityRank
from city where countrycode in ('chn','idn','aus')
)
select * from topCities where cityRank=1;

-- LEAD
use rankingdb;
select* from sales1;

select * ,

lead( sale,1) over (order by fiscal_year asc) as 'Next Sale'

from sales1;

-- lead() lets u access or get value of Next Row(s) in Current ROW.

-- lead( <which column value u wish to access> , <interval> )

select * ,

lead( sale,1) over (order by fiscal_year asc) as 'Next Sale'

from sales1;

-- Real Life use Case

use employees;
select * from salaries;

select emp_no,salary,

lead(salary,1) over ( partition by emp_no order by emp_no asc) as 'NextSalary'


from salaries;

with SalaryHistory
as
(select emp_no,salary,

lead(salary,1) over ( partition by emp_no order by emp_no asc) as 'NextSalary'


from salaries
)
select * , (NextSalary-Salary) as 'IncrementAmount' from SalaryHistory;

You might also like