SQL Simplified
SQL Simplified
By Bemnet Girma
linkedin.com/in/bemnetdev
15+ Topics
70+ Practice Queries
50 SQL Query Questions from 15+ Companies
110+ Frequently Asked SQL Interview Questions
IN JUST 10 PAGES
SQL SIMPLIFIED FOR ALL linkedin.com/in/bemnetdev
KEYWORDS CREATE TABLE
Data is representation of raw facts, measurements, CREATE - to create a new database object such as a table.
figures, or concepts in a formalized manner that have no CREATE TABLE department (
specific meaning.
did varchar(20),
Information is processed (organized or classified) data, name varchar(20) NOT NULL,
which has some meaningful values. CONSTRAINT PK_DEPT PRIMARY KEY(did)
Database is an organized collection of data stored and );
accessed electronically in a computer system.
INSERT DATA
DBMS are software systems that enable users to store,
retrieve, define and manage data in a database easily. INSERT INTO department VALUES
('D1', 'Management'),
RDBMS is a type of DBMS that stores data in a row-based
table structure which connects related data elements. ('D2', 'IT'),
('D3', 'Sales'),
SQL is a database query language used for storing and ('D4', 'HR')
managing data in RDBMS.
did name
DATA TYPES
D1 Management
Data type is a data rule applicable to a particular column. D2 IT
NULL, CHAR, VARCHAR, INT, DATE, FLOAT, BOOLEAN D3 Sales
D4 HR
CONSTRAINTS
Constraints are limitations or restrictions applied to a CREATE “employee” TABLE
column in a table, they are important to maintain data
integrity among tables. CREATE TABLE employee (
eid int,
CHECK - control the values being inserted. name varchar(20) UNIQUE,
NOT NULL - ensure that NULL value has not inserted. join_date date NOT NULL,
department char(2)
UNIQUE – ensure that every column value is unique.
CHECK (dep IN ('D1', 'D2', 'D3')),
PRIMARY KEY – ensure that all values are UNIQUE and salary int,
NOT NULL
manager int,
FOREIGN KEY - create a parent-child r/ship b/n tables CONSTRAINT PK_ID PRIMARY KEY(eid),
COMMANDS CONSTRAINT FK_DID FOREIGN KEY(department)
REFERENCES department(did)
Data Definition Language (DDL) );
DCAT | DROP, CREATE, ALTER, TRUNCATE
eid name join_date dep salary manager
Data Query Language (DQL)
SELECT 101 David 2009-07-14 D1 50000 None
102 Sam 2010-06-24 D1 40000 101
Data Manipulation Language (DML) 103 Alicia 2011-05-11 D2 30000 102
UMID | UPDATE, MERGE, INSERT, DELETE
104 Alex 2012-04-15 D2 20000 102
Data Control Language (DCL) 105 Robbi 2013-08-14 D2 20000 102
GRANT and REVOKE 106 Jack 2014-09-19 D3 8000 101
Transaction Control Language (TCL) 107 Tom 2015-11-12 None 5000 116
COMMIT, SAVEPOINT, ROLLBACK 108 Lily 2016-07-28 D3 1000 106
.
https://platform.stratascratch.com/coding/1000
Revoke multiple privilege 3-lyft-driver-wages?code_type=1
REVOKE INSERT, UPDATE ON Users TO 'Test';
.
OPERATORS https://platform.stratascratch.com/coding/9972-
find-the-base-pay-for-police-
Fetch three employees who earn more than 10000 captains?code_type=1
Comparison (=, >, <, <=, >=, !=), Order by and Limit
SELECT name, salary .
https://platform.stratascratch.com/coding/1002
FROM employee 6-find-all-wineries-which-produce-wines-by-
WHERE salary > 10000 possessing-aromas-of-plum-cherry-rose-or-
ORDER BY name hazelnut?code_type=1
LIMIT 3;
DATE FUNCTIONS
name salary
Alex 20000 Fetch employee data who join on April
Alicia 30000 Extract year, month, day, hour, minute, second from date
David 50000 SELECT *
FROM employee
Fetch products in stock with price range 1000 to 1500 WHERE EXTRACT(MONTH FROM join_date) = '04';
Between, Order by (Descending) AND, IN
SELECT name, brand, price stock eid name join_date dep salary manager
FROM sales 104 Alex 2012-04-15 D2 20000 102
WHERE price BETWEEN 1000 AND 1500
AND stock IN ('1') Fetch todays date
To_Char convert number & date to a character string.
ORDER BY name DESC;
SELECT TO_CHAR(CURRENT_DATE, 'Month dd, yyyy')
name brand price stock AS todays_date;
iPhone 12 Apple 1100.0 True
MacBook Air Apple 1200.0 True todays_date
Galaxy Note 20 Samsung 1200.0 True October 10, 2022
SQL SIMPLIFIED FOR ALL linkedin.com/in/bemnetdev
DISTINCT name
Fetch all brands in sales table Alicia
David
SELECT DISTINCT brand
Ellen
FROM sales;
Ryan
brand Sam
Apple Fetch only employees who work on projects
Samsung SELECT name
Dell FROM employee
.
INTERSECT
https://platform.stratascratch.com/coding/9650- SELECT person
find-the-top-10-ranked-songs-in- FROM project;
2010?code_type=1
name
CASE STATEMENT Alicia
David
Categorize employees based on their salary Sam
SELECT name, salary,
Fetch person who is not an employee but work on project
CASE WHEN salary >= 30000 THEN 'High'
SELECT person
WHEN salary BETWEEN 10000 AND 30000 THEN 'Mid'
WHEN salary < 10000 THEN 'Low'
FROM project
END AS Range EXCEPT
FROM employee SELECT name
FROM employee;
ORDER BY 2 DESC;
person
name salary Range
David 50000 High Ellen
Sam 40000 High Ryan
Alicia 30000 High JOIN
Alex 20000 Mid
Robbi 10000 Mid
Jack 8000 Low
Tom 5000 Low
Lily 5000 Low
https://platform.stratascratch.com/coding/9726-
classify-business-type?code_type=1 INNER JOIN
.
https://platform.stratascratch.com/coding/1008
SELECT person 7-find-all-posts-which-were-reacted-to-with-a-
FROM project; heart?code_type=1
SQL SIMPLIFIED FOR ALL linkedin.com/in/bemnetdev
SELECT E.name, P.proj_name
.
https://platform.stratascratch.com/coding/9913-
order-details?code_type=1 FROM project P
FULL JOIN employee E
ON E.name = P.person;
https://platform.stratascratch.com/coding/9894-
employee-and-manager-salaries?code_type=1 name Proj_name
. None Ecommerce
.
None Inventory
https://platform.stratascratch.com/coding/1007 Alex None
8-find-matching-hosts-and-guests-in-a-way-that- Alicia Inventory
they-are-both-of-the-same-gender-and- David Ecommerce
nationality?code_type=1
Jack None
Lily None
.
Robbi None
https://platform.stratascratch.com/coding/1032
2-finding-user-purchases?code_type=1 Sam Inventory
Tom None
https://platform.stratascratch.com/coding/1017
common columns. 6-bikes-last-used?code_type=1
CONCATINATE
https://platform.stratascratch.com/coding/1006
Create a mail address for all employees using their 1-popularity-of-hack?code_type=1
name and department with lowercase & @tcs.in domain. .
https://platform.stratascratch.com/coding/9622-
FROM employee E number-of-bathrooms-and-
JOIN department D ON D.did = E.dept; bedrooms?code_type=1
https://platform.stratascratch.com/coding/9653-
david.manag@tcs.in David Management count-the-number-of-user-events-performed-by-
sam.manag@tcs.in Sam Management macbookpro-users?code_type=1
alicia.it@tcs.in Alicia IT
alex.it@tcs.in Alex IT https://platform.stratascratch.com/coding/1015
robbi.it@tcs.in Robbi IT 6-number-of-units-per-nationality?code_type=1
jack.sales@tcs.in Jack Sales .
https://platform.stratascratch.com/coding/9915-
GROUP BY AND AGGREGATION FUNCTIONS highest-cost-orders?code_type=1
Fetch total employee, min, max, average & total salary
of each department which have less than 3 employees.
Count, Min, Max, Avg, Sum, Group by, Having https://platform.stratascratch.com/coding/1004
9-reviews-of-categories?code_type=1
SELECT D.name, COUNT(1) AS emp, .
https://platform.stratascratch.com/coding/9897-
SELECT name, salary highest-salary-in-department?code_type=1
FROM employee
WHERE salary > ( https://platform.stratascratch.com/coding/9814-
SELECT AVG(salary) counting-instances-in-text?code_type=1
FROM employee
); CORRELATED SUBQUERY
Find the employees in each department who earn more
name salary than the average salary in that department
David 50000 sub query which is related to outer query like recursion.
Sam 40000 SELECT name, dept, salary
Alicia 30000 FROM employee E1
WHERE salary > (
SELECT AVG(salary)
.
https://platform.stratascratch.com/coding/1030
8-salaries-differences?code_type=1 FROM employee E2
WHERE E2.dept = E1.dept
. );
https://platform.stratascratch.com/coding/1035
3-workers-with-the-highest-salaries?code_type=1 name dept salary
David D1 50000
Alicia D2 30000
MULTIPLE ROW SUB QUERY
The sub query always returns multiple row. Jack D3 8000
.
FROM sales .
https://platform.stratascratch.com/coding/9905-
GROUP BY brand) sales highest-target-under-manager?code_type=1
JOIN (
SELECT AVG(Total_Sales) AS SALES https://platform.stratascratch.com/coding/1035
FROM ( 2-users-by-avg-session-time?code_type=1
SELECT brand, SUM(price) AS Total_Sales .
Why do we write same query twice let’s use "with" clause? WINDOW /ANALYTIC/ FUNCTION
Step 1: Find total sales per each brand (TSPB)
Step 2: Find average sales wrt all brands (ASPAB) Whenever we are using a window function, we
Step 3: Find brand where TSPB > ASPAB 1. can create partitions using by grouping then
2. apply any window function to each of those partitions.
WITH Total_Sales (brand, TSPB) AS
ROW NUMBER
(SELECT S.brand, SUM(price) AS TSPB
Give roll number to all employees with and without dept
FROM sales S
SELECT E.eid, E.name, E.dept,
GROUP BY S.brand),
ROW_NUMBER() OVER() AS Roll,
AVG_SALES (ASPAB) AS
ROW_NUMBER() OVER(PARTITION BY dept) AS Rp
(SELECT AVG(TSPB) AS ASPAB
FROM employee E;
FROM Total_Sales)
SELECT * eid name dept Roll Rp
FROM Total_Sales TS 101 David D1 1 1
102 Sam D1 2 2
JOIN AVG_SALES AV
103 Alicia D2 3 1
ON TS. TSPB > AV.ASPAB;
104 Alex D2 4 2
brand TSPB ASPAB 105 Robbi D2 5 3
Apple 6160.0 4326.666666666666 106 Jack D3 6 1
108 Lily D3 7 2
ADVANTAGES OF USING WITH CLAUSE 107 Tom None 8 1
Easily readable
Fetch 1st employees from each dept to join the company
Easier to maintain and debug
SELECT * FROM (
Improvement of performance
SELECT E.eid, E.name, E.join_date, E.dept,
USE WITH CLAUSE WHEN YOU ARE ROW_NUMBER() OVER(PARTITION BY dept)
trying to use a particular subquery multiple times. AS RNO
writing a very complex SQL query and it becomes FROM employee E) X
difficult to read and understand. WHERE X.RNO < 2;
interested in a particular record from big table data.
eid name Join_date dept RNO
SQL COMMANDS WHICH ALLOW SUB QUERIES 107 Tom 2015-11-12 None 1
[INSERT, UPDATE, DELETE] 101 David 2009-07-14 D1 1
103 Alicia 2011-05-11 D2 1
106 Jack 2014-09-19 D3 1
SQL SIMPLIFIED FOR ALL linkedin.com/in/bemnetdev
RANK and DENSE_RANK name dept salary P_SAL N_SAL P_Co N_Co
Rank all employees in each department based on their David D1 50000 None 40000 None HIGH
salary with and without duplicate rank skipping Sam D1 40000 50000 30000 LOW HIGH
SELECT E.eid, E.name, E.dept, E.salary, Alicia D2 30000 40000 20000 LOW HIGH
RANK() OVER(ORDER BY salary DESC) AS RNK, Alex D2 20000 30000 20000 LOW SAME
DENSE_RANK() OVER(ORDER BY salary DESC) AS Dr Robbi D2 20000 20000 8000 SAME HIGH
Jack D3 8000 20000 5000 LOW HIGH
FROM employee E;
Tom None 5000 8000 5000 LOW SAME
eid name dept salary RNK Dr Lily D3 5000 5000 None SAME None
101 David D1 50000 1 1
.
102 Sam D1 40000 2 2
https://platform.stratascratch.com/coding/1031
103 Alicia D2 30000 3 3 9-monthly-percentage-difference?code_type=1
104 Alex D2 20000 4 4
105 Robbi D2 20000 5 4
106 Jack D3 8000 6 5 FIRST_VALUE and LAST_VALUE
107 Tom None 5000 7 6 Query to display the most & least expensive product
108 Lily D3 5000 7 6 under each category (corresponding to each record)
FIRST_VALUE extracts first record of the partition.
LAST_VALUE extracts last record of the partition.
https://platform.stratascratch.com/coding/9680- SELECT category, name, price,
most-profitable-companies?code_type=1
. FIRST_VALUE(name)
OVER(PARTITION BY category
https://platform.stratascratch.com/coding/1015 ORDER BY price DESC) AS Expensive,
9-ranking-most-active-guests?code_type=1
LAST_VALUE(name)
OVER(PARTITION BY category
.
https://platform.stratascratch.com/coding/1004
6-top-5-states-with-5-star- FROM sales;
businesses?code_type=1
category name price Expensive Cheap
.
Laptop XPS 15 2300 XPS 15 XPS 15
https://platform.stratascratch.com/coding/514- Laptop MacBook Pro 2000 XPS 15 XPS 13
marketing-campaign-success- Laptop XPS 13 2000 XPS 15 XPS 13
advanced?code_type=1 Laptop MacBook Air 1200 XPS 15 MacBook Air
Phone iPhone 13 1300 iPhone 13 iPhone 13
LAG and LEAD Phone Galaxy Note 1200 iPhone 13 Galaxy Note
Fetch a query to display if the salary of an employee is Phone iPhone 12 1100 iPhone 13 iPhone 12
higher, lower or equal to previous and next employee Phone Galaxy S21 1100 iPhone 13 Galaxy S21
LAG extracts previous record. Tablet ipad 7th gen 560 ipad 7th gen ipad 7th gen
LEAD extracts the next record. Tablet Galaxy Tab A7 220 ipad 7th gen Galaxy Tab A7
WITH COMP AS (
SELECT E.eid, E.name, E.dept, E.salary, But, the above result is not correct for cheap column. That
LAG(salary) OVER(ORDER BY eid) AS P_SAL, is b/c of default frame clause SQL is using. What is frame?
LEAD(salary) OVER(ORDER BY eid) AS N_SAL
FROM employee E) FRAME CLAUSE
SELECT *, Fetch least expensive product of each category
Inside each partitions we can again create some subset of
CASE WHEN salary > P_SAL THEN 'HIGH' records which is called as frames. So basically a frame is
WHEN salary < P_SAL THEN 'LOW' a subset of a partition.
WHEN salary = P_SAL THEN 'SAME'
END P_Co, NB: Default FRAME CLAUSE is RANGE BETWEEN
UNBOUNDED PRECEDING AND CURRENT ROW. This
CASE WHEN salary > N_SAL THEN 'HIGH'
means our frame is all records between first record and
WHEN salary < N_SAL THEN 'LOW' current record.
WHEN salary = N_SAL THEN 'SAME'
END N_Co Not every window function will really be impacted by this
FROM COMP; default FRAME CLAUSE, It generally impacts the last_value,
nth_value and almost all aggregate functions.
SQL SIMPLIFIED FOR ALL linkedin.com/in/bemnetdev
SELECT category, brand, name, price, SELECT brand, name,
FIRST_VALUE(name) OVER(PARTITION BY category CASE WHEN X.BUCKETS = 1 THEN 'EXPENSIVE'
SELECT category, brand, name, price WHEN X.BUCKETS = 2 THEN 'MIDRANGE'
FROM ( WHEN X.BUCKETS = 3 THEN 'CHEAP'
SELECT *, END PRICE_RANGE
LAST_VALUE(name) FROM (
OVER(PARTITION BY category SELECT *,
ORDER BY price DESC NTILE(3)
RANGE BETWEEN UNBOUNDED PRECEDING OVER(ORDER BY price DESC) AS BUCKETS
AND UNBOUNDED FOLLOWING) AS cheap FROM sales
FROM sales) X WHERE category = 'Phone') X;
WHERE NAME = cheap; brand name PRICE_RANGE
category brand name Price Apple iPhone 13 EXPENSIVE
Laptop Apple MacBook Air 1200 Samsung Galaxy Note 20 EXPENSIVE
Phone Samsung Galaxy S21 1100 Apple iPhone 12 MIDRANGE
Tablet Samsung Galaxy Tab A7 220 Samsung Galaxy S21 CHEAP
.