Newton School Free SQL Handbook
Newton School Free SQL Handbook
Newton School Free SQL Handbook
INTER
CRACKER
Newton School Handbook
Dhananjay Dadheech
Preface
Hello Newtonians!
Ever stare blankly at the question during an interview? You're not alone. Mastering SQL is
crucial for landing your dream job, but navigating interview nerves and tricky questions can
be daunting.
This handbook arms you with the most potent SQL questions that frequently appear. Here I
have collated the questions from the best possible open sources in my opinion which can
give you the “FEEL” of SQL and help you in your interviews.
NOTE : This Handbook assumes that you are familiar with SQL in terms of writing queries
and fundamentally clear with the concepts like aggregates, window functions and joins.
Lastly, I wish you all the best for your upcoming interviews and your future endeavours.
Cheers!
Index
TOPICS Page
Order of execution 1
Theoretical Questions 41
FROM clause
ON clause
OUTER clause
WHERE clause
GROUP BY clause
HAVING clause
SELECT clause (Window Functions are executed with the select clause)
DISTINCT clause
ORDER BY clause
LIMIT clause
2
WINDOW FUNCTIONS
Here is Table Structure:
Q1. Calculate the rank according to the hire date of the employee and
order by the salary of the employee
from emp
order by sal;
3
Q2. Calculate the rank according to the hire date of the employee
and order by the salary of the employee
from emp
order by sal;
Q3. Calculate the rank according to the salary of the employee and
order by the salary of the employee in ascending order
select empno, ename, job, hiredate, sal,
rank()over(order by sal) as rnk,
dense_rank()
over( order by sal
)as sal_dense_rnk
from emp
order by sal
;
4
) as cum_dist,ntile(4)
over(
order by gross_sales) as ntil
from movies;
Output:
Planets:
Q5. Rank the planets (mars, venus, pluto, mercury, neptune)by their
radius in Desc order. Nulls should be displayed last.
select p.name as planet,m.name as moon, m.radius,
row_number()
over(
order by m.radius desc) as rnk
from
planets p, moons m
where p.name =m.planet_name and p.name in
('Mars','Venus','Pluto', 'Mercury', 'Neptune')
7
Here is a table:
Q8. I need a running total of total ocean coverage for water type
across the world, largest to smallest
select name, type, square_km,
sum(square_km) over (
partition by type
order by square_km desc
rows between 1 preceding and 1 following
) as tot
from water
order by square_km desc
;
9
Q11. compare daily uber trips in new york city with 2nd lowest trip
count from July to September.
select trip_Date, trip_count,nth_value(trip_count, 2)
over(
order by trip_count
rows between unbounded preceding and unbounded following)as
secnd_lowest from trips
where extract(year from trip_date) = 2014
and extract(month from trip_date) in (7,8,9)
order by trip_date;
Here is a table:
13
Q12. Fill in the blanks for the null values in DEPTNPO table and
count the employees according to departments.
select dept, count(dept)from
(select seq, empno, ename, job, mgr, hiredate, sal, deptno,
last_value(deptno ignore nulls)
over(order by seq) as deptfrom external_emp) agroup by dept
order by dept
Q13. Only show the dates when the status of the order changed for
that particular order. Remove the remaining data.
select order_id, status_date,lead_status,status,
lag(status_date)
over(partition by order_id order by status_date ) from_date,
status_date to_date
from(select
order_id,
status_date,
status,
lag(status) over (partition by order_id order by
status_date) lag_status,
lead(status) over (partition by order_id order by
status_date) lead_status
from ORDERS)a
Employee Table -
Departments Table -
dept_id INT,
dept_name VARCHAR(10)
);
Orders Table -
order_amount INT,
customer_gender CHAR(6)
);
• SELECT emp_id, COUNT(*): This part selects the emp_id column and calculates the
count of rows for each emp_id.
• FROM emp: Specifies that you're querying the emp table.
• GROUP BY emp_id: Groups the rows in the emp table by the emp_id column, so you
get one row for each unique emp_id.
• HAVING COUNT(*) > 1: This is a filter condition that ensures only rows with a count
greater than 1 (i.e., duplicates) are included in the result.
WITH cte AS (...): This defines a Common Table Expression (CTE) named cte. The CTE
selects all columns from the emp table and adds a new column rn using
the ROW_NUMBER() window function. The PARTITION BY emp_id clause means that the
row numbers are assigned separately for each unique emp_id, and the ORDER BY
emp_id clause orders the rows within each partition by emp_id.
DELETE FROM cte WHERE rn > 1;: This statement deletes rows from the CTE cte where the
row number (rn) is greater than 1. Since the ROW_NUMBER() function assigns a value of 1
17
to the first occurrence of each emp_id and increments it for subsequent duplicates, this
effectively deletes all but one instance of each duplicate emp_id.
1. UNION:
This query will return a result set with only distinct rows.
2. UNION ALL:
This query will return a result set that includes all rows, including
duplicates.
RANK():
• If multiple rows have the same values and are assigned the
same rank, the next rank will skip the number of tied rows
19
SELECT
emp_id,
emp_name,
salary,
RANK() OVER(ORDER BY salary DESC) AS rnk
FROM
emp;
ROW_NUMBER():
SELECT
emp_id,
emp_name,
salary,
ROW_NUMBER() OVER(ORDER BY salary DESC) AS rn
20
FROM
emp;
DENSE_RANK():
• If multiple rows have the same values, they are assigned the
same rank, and the next rank does not skip any values. It
provides a dense ranking without gaps for tied rows.
SELECT
emp_id,
emp_name,
salary,
DENSE_RANK() OVER(ORDER BY salary DESC) AS rn
FROM
emp;
SELECT
*
FROM
emp AS e
LEFT JOIN
department AS d ON e.department_id = d.dept_id
WHERE d.dept_id IS NULL;
1. SELECT *: This part of the query selects all columns (*) from
the result set.
SELECT *
FROM (
SELECT
emp_name,
salary,
department_id,
DENSE_RANK() OVER (PARTITION BY department_id ORDER BY salary
DESC) AS rn
FROM emp
) AS a
WHERE rn = 2;
4. The outer query selects all columns (*) from the result of
the inner query (a).
SELECT *
FROM orders
WHERE UPPER(customer_name) = 'PRADEEP';
2. FROM orders: This clause indicates the source table for the
query, which is the orders table. The query will retrieve data
from this table.
24
So, the overall result of this query will be a list of all transactions
(rows from the orders table) where the customer's name, regardless
of its original case, matches 'PRADEEP' in uppercase. This query
allows you to find all transactions made by customers named
"Pradeep" while ignoring differences in capitalization.
SELECT
e1.emp_id,
e1.emp_name,
e2.emp_name AS manager_name,
e1.salary,
e2.salary AS manager_salary
FROM
emp AS e1
INNER JOIN
25
1. SELECT Clause:
2. FROM Clause:
• FROM emp AS e1: This clause specifies the source table for the
query and aliases it as e1. It represents the employees
(subordinates).
4. WHERE Clause:
So, the overall result of this query will be a list of employees and
their respective managers, but it only includes rows where the
manager’s salary is higher than that of the employee. This query
helps identify employees with managers who have a higher salary.
UPDATE orders
SET
customer_gender = CASE
WHEN customer_gender = 'Male' THEN 'Female'
27
1. UPDATE Clause:
2. SET Clause:
3. CASE Statement:
a) Inner Join: The INNER JOIN keyword selects records that have
matching values in both tables.
the right table (table2). The result is NULL from the right side, if
there is no match.
c) Right Join: The RIGHT JOIN keyword returns all records from
the right table (table2), and the matched records from the left table
(table1). The result is NULL from the left side, when there is no
match.
e) Cross Join : is used to combine each row of one table with each
row of another table, return the product of the sets of rows from the
tables that are joined.
30
Yes, you can update data in the table using a view by using a simple
update statements.
Indexes are special lookup tables that are used by database search
engine for faster retrieval of the data. Simply put, an index is a
pointer to data in a table. It is like an Index page of a book
A SQL query produce a complete result set, but there are times when
the results are best processed one row at a time. Opening a cursor on
a result set allows processing the result set one row at a time.
Performance of Cursor:
Advantages:
Disadvantage:
These tables allow you to hold inserted, deleted and updated values
during insert, delete and update DML operations on a table in SQL
Server. Magic Tables are invisible tables or virtual tables, you can
see them only with the help Triggers.
1. Inserted
2. Deleted
1. Primary key will not accept NULL values whereas Unique key can
accept one NULL value.
2. A table can have only primary key whereas there can be multiple
unique key on a table.
varchar- used for normal strings (not UNI-code) data types. It uses
1byte per character
Coalesce: Returns the first non-null value passed into the param list.
3) Using DMVs
like: sys.dm_exec_requests/sys.dm_tran_locks/sys.dm_os
_waiting_tasks
41
Ans: We can use the “CHECK” constraint while creating the column
in the table.
id int,
Age int CHECK (Age>0)
)
Theoretical Questions
How would you make sure that when I insert the employee
record, I am inserting a correct department id (i.e. a
department id that exists inside the department table)?
Ans: I can create a trigger. This trigger will execute when an insert
statement is fired on the employee table. This trigger will check if
the department id for this new record exists or not in the
department table. This way I will be able to mock the foreign key
behavior without creating it.
Ans: If you are aware of the primary key, you would know that a
primary key automatically creates a clustered index. So basically the
interviewer wanted to ask me the difference between a clustered and
a non-clustered index. Below was my answer:
Ans: If you want to use transaction you must use a stored procedure
as transactions are not allowed in the function.
Q46) Suppose I have created a global temporary table say GT1 and I
have inserted 5 records in it. I am still logged in to the system and
then you now have also logged into the system. And then you try to
access the GT1 table. a) Will you be able to access GT1? Ans: Yes
b) will you see an empty table or will you see 5 records? Ans: I will
see all 5 records
In short, you must drop the global temporary table otherwise it will
continue to live inside the database memory. It will continue to exist
until the SQL server is recycled or restarted.
Ans: We would write a query with a switch case where if the value is
1 we would update it with 0 and vice-versa.
Ans: We can have a student table with the primary key student id.
And we can have a course table with the primary key course id. We
can have a third table (a junction table) where we can map students
to their respective courses.
Ans: We can have one table with a list of all types and each row will
have a parent id. So, if I have added Milkshake to the table its parent
will be Milk-based, milk-based parent id will be sweets. Sweets
parent id will be Snaks and Food will be the root element.
In which case would the SQL server use the Index, that I
have created on Stud_Name?
Ans: We need to write the After triggers. The after triggers have
access to magic tables that have the details of recently updated or
deleted records. We can access these magic table “INSERTED” and
“DELETED” only via After trigger. These tables are not accessible
otherwise. We can read data from “DELETED” magic table and add
record to the audit table.
48
SELECT Emp_Salary
WHERE N-1 = (
)
49
When PK is present
from EmployeeDetails
50
group by Emp_Gender;
Note that here we need all the details of employee table and only
matching records from department table. Thus, here we need to
do Left Join.
The LEFT JOIN keyword returns all records from the left table
(table1), and the matched records from the right table (table2). The
result is NULL from the right side, if there is no match.
Q61) Write a SQL query to fetch all the Employees who are
also managers from EmployeeDetails table.
Q62) Write a SQL query to fetch only odd rows from table.
select * from
52
) e where e.tRowNumber%2!=0
Competitive questions
These questions can help you understand how to approach different coding problems.
Specially when you are giving a screening test. Advice would be to solve the question on
your own or create a problem solving approach in a timed environment before looking at
the answer.
Q1.
Table: Sales
+-------------+-------+
+-------------+-------+
| sale_id | int |
| product_id | int |
| year | int |
| quantity | int |
| price | int |
+-------------+-------+
Each row of this table shows a sale on the product product_id in a certain year.
Table: Product
+--------------+---------+
+--------------+---------+
| product_id | int |
| product_name | varchar |
+--------------+---------+
Each row of this table indicates the product name of each product.
Write an SQL query that reports the product_name, year, and price for each sale_id in
the Sales table.
Example 1:
Input:
Sales table:
+---------+------------+------+----------+-------+
+---------+------------+------+----------+-------+
+---------+------------+------+----------+-------+
Product table:
+------------+--------------+
| product_id | product_name |
+------------+--------------+
| 100 | Nokia |
| 200 | Apple |
| 300 | Samsung |
+------------+--------------+
Output:
+--------------+-------+-------+
+--------------+-------+-------+
+--------------+-------+-------+
Explanation:
From sale_id = 1, we can conclude that Nokia was sold for 5000 in the year 2008.
From sale_id = 2, we can conclude that Nokia was sold for 5000 in the year 2009.
From sale_id = 7, we can conclude that Apple was sold for 9000 in the year 2011.
Code
SELECT DISTINCT
FROM
INNER JOIN
Product AS P
USING (product_id);
Q2.
Write an SQL query that reports the total quantity sold for every product id.
Output:
+--------------+----------------+
| product_id | total_quantity |
+--------------+----------------+
| 100 | 22 |
| 200 | 15 |
+--------------+----------------+
56
Code
FROM Sales
GROUP BY product_id
Q2.
Problem
Table: Activity
+--------------+---------+
+--------------+---------+
| player_id | int |
| device_id | int |
| event_date | date |
| games_played | int |
+--------------+---------+
Each row is a record of a player who logged in and played a number of games
(possibly 0) before logging out on someday using some device.
Write an SQL query to report the first login date for each player.
Example 1:
57
Input:
Activity table:
+-----------+-----------+------------+--------------+
+-----------+-----------+------------+--------------+
| 1 | 2 | 2016-03-01 | 5 |
| 1 | 2 | 2016-05-02 | 6 |
| 2 | 3 | 2017-06-25 | 1 |
| 3 | 1 | 2016-03-02 | 0 |
| 3 | 4 | 2018-07-03 | 5 |
+-----------+-----------+------------+--------------+
Output:
+-----------+-------------+
| player_id | first_login |
+-----------+-------------+
| 1 | 2016-03-01 |
| 2 | 2017-06-25 |
| 3 | 2016-03-02 |
+-----------+-------------+
Code
FROM activity
IN (
FROM activity
58
GROUP BY player_id
Q3.
Problem
Table: Customers
+---------------+---------+
+---------------+---------+
| customer_id | int |
| name | varchar |
| country | varchar |
+---------------+---------+
Table: Product
+---------------+---------+
+---------------+---------+
| product_id | int |
| description | varchar |
| price | int |
+---------------+---------+
Table: Orders
+---------------+---------+
+---------------+---------+
| order_id | int |
| customer_id | int |
| product_id | int |
| order_date | date |
| quantity | int |
+---------------+---------+
Order_date is the date in format ('YYYY-MM-DD') when the order was shipped.
Write an SQL query to report the customer_id and customer_name of customers who
have spent at least $100 in each month of June and July 2020.
Example 1:
Input:
Customers table:
+--------------+-----------+-------------+
+--------------+-----------+-------------+
| 1 | Winston | USA |
| 2 | Jonathan | Peru |
| 3 | Moustafa | Egypt |
60
+--------------+-----------+-------------+
Product table:
+--------------+-------------+-------------+
+--------------+-------------+-------------+
| 10 | LC Phone | 300 |
| 20 | LC T-Shirt | 10 |
| 30 | LC Book | 45 |
| 40 | LC Keychain | 2 |
+--------------+-------------+-------------+
Orders table:
+--------------+-------------+-------------+-------------+-----------+
+--------------+-------------+-------------+-------------+-----------+
| 1 | 1 | 10 | 2020-06-10 | 1 |
| 2 | 1 | 20 | 2020-07-01 | 1 |
| 3 | 1 | 30 | 2020-07-08 | 2 |
| 4 | 2 | 10 | 2020-06-15 | 2 |
| 5 | 2 | 40 | 2020-07-01 | 10 |
| 6 | 3 | 20 | 2020-06-24 | 2 |
| 7 | 3 | 30 | 2020-06-25 | 2 |
| 9 | 3 | 30 | 2020-05-08 | 3 |
+--------------+-------------+-------------+-------------+-----------+
Output:
+--------------+------------+
| customer_id | name |
+--------------+------------+
| 1 | Winston |
+--------------+------------+
Explanation:
Jonathan spent $600 (300 * 2) in June and $20 ( 2 * 10) in July 2020.
Code
GROUP BY customer_id
Q4.
Problem
Table: Products
+------------------+---------+
+------------------+---------+
| product_id | int |
| product_name | varchar |
| product_category | varchar |
+------------------+---------+
Table: Orders
62
+---------------+---------+
+---------------+---------+
| product_id | int |
| order_date | date |
| unit | int |
+---------------+---------+
There is no primary key for this table. It may have duplicate rows.
Write an SQL query to get the names of products that have at least 100 units ordered
in February 2020 and their amount.
Example 1:
Input:
Products table:
+-------------+-----------------------+------------------+
+-------------+-----------------------+------------------+
| 3 | HP | Laptop |
| 4 | Lenovo | Laptop |
+-------------+-----------------------+------------------+
Orders table:
+--------------+--------------+----------+
+--------------+--------------+----------+
| 1 | 2020-02-05 | 60 |
| 1 | 2020-02-10 | 70 |
| 2 | 2020-01-18 | 30 |
| 2 | 2020-02-11 | 80 |
| 3 | 2020-02-17 | 2 |
| 3 | 2020-02-24 | 3 |
| 4 | 2020-03-01 | 20 |
| 4 | 2020-03-04 | 30 |
| 4 | 2020-03-04 | 60 |
| 5 | 2020-02-25 | 50 |
| 5 | 2020-02-27 | 50 |
| 5 | 2020-03-01 | 50 |
+--------------+--------------+----------+
Output:
+--------------------+---------+
| product_name | unit |
+--------------------+---------+
+--------------------+---------+
Explanation:
Code
64
from Products a
group by a.product_id
Q5.
Problem
Table: Activity
+--------------+---------+
+--------------+---------+
| player_id | int |
| device_id | int |
| event_date | date |
| games_played | int |
+--------------+---------+
Each row is a record of a player who logged in and played a number of games
(possibly 0) before logging out on someday using some device.
Write an SQL query to report the first login date for each player.
Example 1:
65
Input:
Activity table:
+-----------+-----------+------------+--------------+
+-----------+-----------+------------+--------------+
| 1 | 2 | 2016-03-01 | 5 |
| 1 | 2 | 2016-05-02 | 6 |
| 2 | 3 | 2017-06-25 | 1 |
| 3 | 1 | 2016-03-02 | 0 |
| 3 | 4 | 2018-07-03 | 5 |
+-----------+-----------+------------+--------------+
Output:
+-----------+-------------+
| player_id | first_login |
+-----------+-------------+
| 1 | 2016-03-01 |
| 2 | 2017-06-25 |
| 3 | 2016-03-02 |
+-----------+-------------+
Code
FROM activity
IN (
FROM activity
66
GROUP BY player_id
Q6.
Problem
Table: Product
+--------------+---------+
+--------------+---------+
| product_id | int |
| product_name | varchar |
| unit_price | int |
+--------------+---------+
Each row of this table indicates the name and the price of each product.
Table: Sales
+-------------+---------+
+-------------+---------+
| seller_id | int |
| product_id | int |
| buyer_id | int |
| sale_date | date |
| quantity | int |
| price | int |
67
+-------------+---------+
Each row of this table contains some information about one sale.
Write an SQL query that reports the best seller by total sales price, If there is a tie,
report them all.
Example 1:
Input:
Product table:
+------------+--------------+------------+
+------------+--------------+------------+
| 1 | S8 | 1000 |
| 2 | G4 | 800 |
| 3 | iPhone | 1400 |
+------------+--------------+------------+
Sales table:
+-----------+------------+----------+------------+----------+-------+
+-----------+------------+----------+------------+----------+-------+
| 1 | 1 | 1 | 2019-01-21 | 2 | 2000 |
| 1 | 2 | 2 | 2019-02-17 | 1 | 800 |
| 2 | 2 | 3 | 2019-06-02 | 1 | 800 |
| 3 | 3 | 4 | 2019-05-13 | 2 | 2800 |
+-----------+------------+----------+------------+----------+-------+
Output:
+-------------+
68
| seller_id |
+-------------+
| 1 |
| 3 |
+-------------+
Explanation: Both sellers with id 1 and 3 sold products with the most total price
of 2800.
Code
SELECT seller_id
FROM Sales
GROUP BY seller_id
SELECT SUM(PRICE)
FROM Sales
GROUP BY seller_id
Q7.
Problem
Table: SalesPerson
+-----------------+---------+
+-----------------+---------+
| sales_id | int |
| name | varchar |
69
| salary | int |
| commission_rate | int |
| hire_date | date |
+-----------------+---------+
Each row of this table indicates the name and the ID of a salesperson alongside
their salary, commission rate, and hire date.
Table: Company
Table: Orders
+-------------+------+
+-------------+------+
| order_id | int |
| order_date | date |
| com_id | int |
| sales_id | int |
| amount | int |
+-------------+------+
Each row of this table contains information about one order. This includes the ID
of the company, the ID of the salesperson, the date of the order, and the amount
paid.
Write an SQL query to report the names of all the salespersons who did not have any
orders related to the company with the name “RED”.
Example 1:
Input:
SalesPerson table:
+----------+------+--------+-----------------+------------+
+----------+------+--------+-----------------+------------+
+----------+------+--------+-----------------+------------+
Company table:
+--------+--------+----------+
+--------+--------+----------+
| 1 | RED | Boston |
| 3 | YELLOW | Boston |
| 4 | GREEN | Austin |
+--------+--------+----------+
Orders table:
+----------+------------+--------+----------+--------+
+----------+------------+--------+----------+--------+
| 1 | 1/1/2014 | 3 | 4 | 10000 |
| 2 | 2/1/2014 | 4 | 5 | 5000 |
| 3 | 3/1/2014 | 1 | 1 | 50000 |
| 4 | 4/1/2014 | 1 | 4 | 25000 |
71
+----------+------------+--------+----------+--------+
Output:
+------+
| name |
+------+
| Amy |
| Mark |
| Alex |
+------+
Explanation:
According to orders 3 and 4 in the Orders table, it is easy to tell that only
salesperson John and Pam have sales to company RED, so we report all the other
names in the table salesperson.
Code
SELECT
s.name
FROM
salesperson s
WHERE
o.sales_id
FROM
orders o
LEFT JOIN
WHERE
c.name = 'RED')
;
72
Q8.
Problem
Table: NewYork
+-------------+------+
+-------------+------+
| student_id | int |
| score | int |
+-------------+------+
Each row contains information about the score of one student from New York
University in an exam.
Table: California
+-------------+------+
+-------------+------+
| student_id | int |
| score | int |
+-------------+------+
Each row contains information about the score of one student from California
University in an exam.
There is a competition between New York University and California University. The
competition is held between the same number of students from both universities.
The university that has more excellent students wins the competition. If the two
universities have the same number of excellent students, the competition ends in a
draw.
“New York University” if New York University wins the competition. “California
University” if California University wins the competition. “No Winner” if the
competition ends in a draw. The query result format is in the following example.
Example 1:
Input:
NewYork table:
+------------+-------+
| student_id | score |
+------------+-------+
| 1 | 90 |
| 2 | 87 |
+------------+-------+
California table:
+------------+-------+
| student_id | score |
+------------+-------+
| 2 | 89 |
| 3 | 88 |
+------------+-------+
Output:
+---------------------+
| winner |
+---------------------+
+---------------------+
Explanation:
New York University has 1 excellent student, and California University has 0
excellent students.
Example 2:
74
Input:
NewYork table:
+------------+-------+
| student_id | score |
+------------+-------+
| 1 | 89 |
| 2 | 88 |
+------------+-------+
California table:
+------------+-------+
| student_id | score |
+------------+-------+
| 2 | 90 |
| 3 | 87 |
+------------+-------+
Output:
+-----------------------+
| winner |
+-----------------------+
| California University |
+-----------------------+
Explanation:
New York University has 0 excellent students, and California University has 1
excellent student.
Example 3:
Input:
NewYork table:
+------------+-------+
| student_id | score |
+------------+-------+
75
| 1 | 89 |
| 2 | 90 |
+------------+-------+
California table:
+------------+-------+
| student_id | score |
+------------+-------+
| 2 | 87 |
| 3 | 99 |
+------------+-------+
Output:
+-----------+
| winner |
+-----------+
| No Winner |
+-----------+
Explanation:
Both New York University and California University have 1 excellent student.
Code
SELECT (CASE
WHEN (SELECT COUNT(score) FROM NewYork WHERE score >= 90) > (SELECT
COUNT(score) FROM California WHERE score >= 90) THEN 'New York University'
WHEN (SELECT COUNT(score) FROM NewYork WHERE score >= 90) < (SELECT
COUNT(score) FROM California WHERE score >= 90) THEN 'California University'
;
76
Q9.
Problem
Table: Weather
+---------------+---------+
+---------------+---------+
| id | int |
| recordDate | date |
| temperature | int |
+---------------+---------+
id is the primary key for this table. This table contains information about the
temperature in a certain day.
Write an SQL query to find all dates’ id with higher temperature compared to its
previous dates (yesterday).
Weather
+----+------------+-------------+
| id | recordDate | Temperature |
+----+------------+-------------+
| 1 | 2015-01-01 | 10 |
| 2 | 2015-01-02 | 25 |
| 3 | 2015-01-03 | 20 |
| 4 | 2015-01-04 | 30 |
+----+------------+-------------+
Result table:
77
+----+
| id |
+----+
| 2 |
| 4 |
+----+
In 2015-01-02, temperature was higher than the previous day (10 -> 25).
In 2015-01-04, temperature was higher than the previous day (30 -> 20).
Code
SELECT w1.id AS Id
FROM weather w1
JOIN weather w2
ON DATEDIFF(w1.recordDate, w2.recordDate) = 1
Q10.
Problem
Table: Department
+-------------+---------+
+-------------+---------+
| id | int |
| revenue | int |
78
| month | varchar |
+-------------+---------+
The table has information about the revenue of each department per month.
Write an SQL query to reformat the table such that there is a department id column
and a revenue column for each month.
Example 1:
Input:
Department table:
+------+---------+-------+
| id | revenue | month |
+------+---------+-------+
| 1 | 8000 | Jan |
| 2 | 9000 | Jan |
| 3 | 10000 | Feb |
| 1 | 7000 | Feb |
| 1 | 6000 | Mar |
+------+---------+-------+
Output:
+------+-------------+-------------+-------------+-----+-------------+
+------+-------------+-------------+-------------+-----+-------------+
+------+-------------+-------------+-------------+-----+-------------+
79
Note that the result table has 13 columns (1 for the department id + 12 for the
months).
Code
select id,
sum(case when month = 'jan' then revenue else null end) as Jan_Revenue,
sum(case when month = 'feb' then revenue else null end) as Feb_Revenue,
sum(case when month = 'mar' then revenue else null end) as Mar_Revenue,
sum(case when month = 'apr' then revenue else null end) as Apr_Revenue,
sum(case when month = 'may' then revenue else null end) as May_Revenue,
sum(case when month = 'jun' then revenue else null end) as Jun_Revenue,
sum(case when month = 'jul' then revenue else null end) as Jul_Revenue,
sum(case when month = 'aug' then revenue else null end) as Aug_Revenue,
sum(case when month = 'sep' then revenue else null end) as Sep_Revenue,
sum(case when month = 'oct' then revenue else null end) as Oct_Revenue,
sum(case when month = 'nov' then revenue else null end) as Nov_Revenue,
sum(case when month = 'dec' then revenue else null end) as Dec_Revenue
from department
group by id
order by id
80
Q11.
Problem
Table: Ads
+---------------+---------+
+---------------+---------+
| ad_id | int |
| user_id | int |
| action | enum |
+---------------+---------+
Each row of this table contains the ID of an Ad, the ID of a user, and the action
taken by this user regarding this Ad.
A company is running Ads and wants to calculate the performance of each Ad.
Write an SQL query to find the ctr of each Ad. Round ctr to two decimal points.
Return the result table ordered by ctr in descending order and by ad_id in ascending
order in case of a tie.
Example 1:
Input:
Ads table:
+-------+---------+---------+
+-------+---------+---------+
| 1 | 1 | Clicked |
| 2 | 2 | Clicked |
| 3 | 3 | Viewed |
| 5 | 5 | Ignored |
| 1 | 7 | Ignored |
| 2 | 7 | Viewed |
| 3 | 5 | Clicked |
| 1 | 4 | Viewed |
| 2 | 11 | Viewed |
| 1 | 2 | Clicked |
+-------+---------+---------+
Output:
+-------+-------+
| ad_id | ctr |
+-------+-------+
| 1 | 66.67 |
| 3 | 50.00 |
| 2 | 33.33 |
| 5 | 0.00 |
+-------+-------+
Explanation:
for ad_id = 5, ctr = 0.00, Note that ad_id = 5 has no clicks or views.
Code
FROM Ads
GROUP BY ad_id
Problem
Table: Calls
+-------------+---------+
+-------------+---------+
| from_id | int |
| to_id | int |
| duration | int |
+-------------+---------+
This table does not have a primary key, it may contain duplicates.
This table contains the duration of a phone call between from_id and to_id.
from_id != to_id
83
Write an SQL query to report the number of calls and the total call duration between
each pair of distinct persons (person1, person2) where person1 < person2.
Example 1:
Input:
Calls table:
+---------+-------+----------+
+---------+-------+----------+
| 1 | 2 | 59 |
| 2 | 1 | 11 |
| 1 | 3 | 20 |
| 3 | 4 | 100 |
| 3 | 4 | 200 |
| 3 | 4 | 200 |
| 4 | 3 | 499 |
+---------+-------+----------+
Output:
+---------+---------+------------+----------------+
+---------+---------+------------+----------------+
| 1 | 2 | 2 | 70 |
| 1 | 3 | 1 | 20 |
| 3 | 4 | 4 | 999 |
+---------+---------+------------+----------------+
Explanation:
Users 1 and 2 had 2 calls and the total duration is 70 (59 + 11).
Users 3 and 4 had 4 calls and the total duration is 999 (100 + 200 + 200 + 499).
Code
GREATEST(from_id,to_id) as person2,
COUNT(*) as call_count,
SUM(duration) as total_duration
FROM Calls
GROUP BY person1,person2;
Q13.
Problem
Table: Customers
+---------------+---------+
+---------------+---------+
| customer_id | int |
| name | varchar |
+---------------+---------+
Table: Orders
+---------------+---------+
+---------------+---------+
| order_id | int |
| order_date | date |
| customer_id | int |
| product_id | int |
+---------------+---------+
No customer will order the same product more than once in a single day.
Table: Products
+---------------+---------+
+---------------+---------+
| product_id | int |
| product_name | varchar |
| price | int |
+---------------+---------+
Write an SQL query to find the most frequently ordered product(s) for each
customer.
The result table should have the product_id and product_name for each customer_id
who ordered at least one order.
Example 1:
Input:
Customers table:
86
+-------------+-------+
| customer_id | name |
+-------------+-------+
| 1 | Alice |
| 2 | Bob |
| 3 | Tom |
| 4 | Jerry |
| 5 | John |
+-------------+-------+
Orders table:
+----------+------------+-------------+------------+
+----------+------------+-------------+------------+
| 1 | 2020-07-31 | 1 | 1 |
| 2 | 2020-07-30 | 2 | 2 |
| 3 | 2020-08-29 | 3 | 3 |
| 4 | 2020-07-29 | 4 | 1 |
| 5 | 2020-06-10 | 1 | 2 |
| 6 | 2020-08-01 | 2 | 1 |
| 7 | 2020-08-01 | 3 | 3 |
| 8 | 2020-08-03 | 1 | 2 |
| 9 | 2020-08-07 | 2 | 3 |
| 10 | 2020-07-15 | 1 | 2 |
+----------+------------+-------------+------------+
Products table:
+------------+--------------+-------+
+------------+--------------+-------+
| 1 | keyboard | 120 |
| 2 | mouse | 80 |
| 3 | screen | 600 |
87
+------------+--------------+-------+
Output:
+-------------+------------+--------------+
+-------------+------------+--------------+
| 1 | 2 | mouse |
| 2 | 1 | keyboard |
| 2 | 2 | mouse |
| 2 | 3 | screen |
| 3 | 3 | screen |
| 4 | 1 | keyboard |
+-------------+------------+--------------+
Explanation:
Alice (customer 1) ordered the mouse three times and the keyboard one time, so the
mouse is the most frequently ordered product for them.
Bob (customer 2) ordered the keyboard, the mouse, and the screen one time, so
those are the most frequently ordered products for them.
Tom (customer 3) only ordered the screen (two times), so that is the most
frequently ordered product for them.
Jerry (customer 4) only ordered the keyboard (one time), so that is the most
frequently ordered product for them.
John (customer 5) did not order anything, so we do not include them in the result
table.
Code
FROM (
FROM Orders O
88
JOIN Products P
ON O.product_id = P.product_id
) temp
WHERE rnk = 1
Q14.
Problem
Table: Customers
+---------------------+---------+
+---------------------+---------+
| customer_id | int |
| customer_name | varchar |
+---------------------+---------+
Table: Orders
+---------------+---------+
+---------------+---------+
| order_id | int |
| customer_id | int |
| product_name | varchar |
+---------------+---------+
89
Write an SQL query to report the customer_id and customer_name of customers who
bought products “A”, “B” but did not buy the product “C” since we want to
recommend them to purchase this product.
Example 1:
Input:
Customers table:
+-------------+---------------+
| customer_id | customer_name |
+-------------+---------------+
| 1 | Daniel |
| 2 | Diana |
| 3 | Elizabeth |
| 4 | Jhon |
+-------------+---------------+
Orders table:
+------------+--------------+---------------+
+------------+--------------+---------------+
| 10 | 1 | A |
| 20 | 1 | B |
| 30 | 1 | D |
| 40 | 1 | C |
| 50 | 2 | A |
| 60 | 3 | A |
| 70 | 3 | B |
| 80 | 3 | D |
90
| 90 | 4 | C |
+------------+--------------+---------------+
Output:
+-------------+---------------+
| customer_id | customer_name |
+-------------+---------------+
| 3 | Elizabeth |
+-------------+---------------+
Explanation: Only the customer_id with id 3 bought the product A and B but not the
product C.
Code
group by a.customer_id
Q15.
Problem
Table: Tree
+-------------+------+
+-------------+------+
| id | int |
91
| p_id | int |
+-------------+------+
Each row of this table contains information about the id of a node and the id of
its parent node in a tree.
Example 1:
Input:
Tree table:
+----+------+
| id | p_id |
+----+------+
| 1 | null |
| 2 | 1 |
| 3 | 1 |
92
| 4 | 2 |
| 5 | 2 |
+----+------+
Output:
+----+-------+
| id | type |
+----+-------+
| 1 | Root |
| 2 | Inner |
| 3 | Leaf |
| 4 | Leaf |
| 5 | Leaf |
+----+-------+
Explanation:
Node 1 is the root node because its parent node is null and it has child nodes 2
and 3.
Node 2 is an inner node because it has parent node 1 and child node 4 and 5.
Nodes 3, 4, and 5 are leaf nodes because they have parent nodes and they do not
have child nodes.
Example 2:
Input:
Tree table:
+----+------+
| id | p_id |
+----+------+
| 1 | null |
+----+------+
Output:
93
+----+-------+
| id | type |
+----+-------+
| 1 | Root |
+----+-------+
Explanation: If there is only one node on the tree, you only need to output its
root attributes.
Code
SELECT
atree.id,
IF(ISNULL(atree.p_id),
'Root',
FROM
tree atree
ORDER BY atree.id
Q16.
Table: Seat
+-------------+---------+
+-------------+---------+
| id | int |
| student | varchar |
+-------------+---------+
Each row of this table indicates the name and the ID of a student.
94
id is a continuous increment.
Write an SQL query to swap the seat id of every two consecutive students. If the
number of students is odd, the id of the last student is not swapped.
Example 1:
Input:
Seat table:
+----+---------+
| id | student |
+----+---------+
| 1 | Abbot |
| 2 | Doris |
| 3 | Emerson |
| 4 | Green |
| 5 | Jeames |
+----+---------+
Output:
+----+---------+
| id | student |
+----+---------+
| 1 | Doris |
| 2 | Abbot |
| 3 | Green |
| 4 | Emerson |
| 5 | Jeames |
+----+---------+
Explanation:
95
Note that if the number of students is odd, there is no need to change the last
one's seat.
Code
SELECT
FROM
seat s1
LEFT JOIN
ORDER BY s1.id;
Q17.
Problem
Write a SQL query to find all numbers that appear at least three times consecutively.
+----+-----+
| Id | Num |
+----+-----+
| 1 | 1 |
| 2 | 1 |
| 3 | 1 |
| 4 | 2 |
| 5 | 1 |
| 6 | 2 |
| 7 | 2 |
+----+-----+
96
For example, given the above Logs table, 1 is the only number that appears
consecutively for at least three times.
+-----------------+
| ConsecutiveNums |
+-----------------+
| 1 |
+-----------------+
Code
FROM
Logs l1,
Logs l2,
Logs l3
Q18.
Problem
Table: Sales
+-------------+-------+
+-------------+-------+
97
| sale_id | int |
| product_id | int |
| user_id | int |
| quantity | int |
+-------------+-------+
Each row of this table shows the ID of the product and the quantity purchased by a
user.
Table: Product
+-------------+------+
+-------------+------+
| product_id | int |
| price | int |
+-------------+------+
Write an SQL query that reports for each user the product id on which the user
spent the most money. In case the same user spent the most money on two or more
products, report all of them.
Example 1:
Input:
Sales table:
+---------+------------+---------+----------+
+---------+------------+---------+----------+
| 1 | 1 | 101 | 10 |
98
| 2 | 3 | 101 | 7 |
| 3 | 1 | 102 | 9 |
| 4 | 2 | 102 | 6 |
| 5 | 3 | 102 | 10 |
| 6 | 1 | 102 | 6 |
+---------+------------+---------+----------+
Product table:
+------------+-------+
| product_id | price |
+------------+-------+
| 1 | 10 |
| 2 | 25 |
| 3 | 15 |
+------------+-------+
Output:
+---------+------------+
| user_id | product_id |
+---------+------------+
| 101 | 3 |
| 102 | 1 |
| 102 | 2 |
| 102 | 3 |
+---------+------------+
Explanation:
User 101:
User 102:
Code
FROM Sales
),
-- Step 2: Rank the user purchases based on total amount spent on each product
user_spent AS (
FROM user_spent
WHERE rk = 1
Q19.
100
Problem
Table: Customers
+---------------+---------+
+---------------+---------+
| customer_id | int |
| customer_name | varchar |
+---------------+---------+
Each row of this table contains the name and the id customer.
Write an SQL query to find the missing customer IDs. The missing IDs are ones that
are not in the Customers table but are in the range between 1 and the maximum
customer_id present in the table.
Example 1:
Input:
Customers table:
+-------------+---------------+
| customer_id | customer_name |
+-------------+---------------+
| 1 | Alice |
| 4 | Bob |
| 5 | Charlie |
+-------------+---------------+
Output:
+-----+
101
| ids |
+-----+
| 2 |
| 3 |
+-----+
Explanation:
The maximum customer_id present in the table is 5, so in the range [1,5], IDs 2
and 3 are missing from the table.
Code
SELECT 1 as continued_id
UNION
SELECT continued_id + 1
FROM id_seq
FROM id_seq
Q20.
Problem
Table: Delivery
+-----------------------------+---------+
+-----------------------------+---------+
102
| delivery_id | int |
| customer_id | int |
| order_date | date |
| customer_pref_delivery_date | date |
+-----------------------------+---------+
The table holds information about food delivery to customers that make orders at
some date and specify a preferred delivery date (on the same order date or after
it).
If the customer’s preferred delivery date is the same as the order date, then the order
is called immediate; otherwise, it is called scheduled.
The first order of a customer is the order with the earliest order date that the
customer made. It is guaranteed that a customer has precisely one first order.
Write an SQL query to find the percentage of immediate orders in the first orders of
all customers, rounded to 2 decimal places.
Example 1:
Input:
Delivery table:
+-------------+-------------+------------+-----------------------------+
+-------------+-------------+------------+-----------------------------+
| 1 | 1 | 2019-08-01 | 2019-08-02 |
| 2 | 2 | 2019-08-02 | 2019-08-02 |
| 3 | 1 | 2019-08-11 | 2019-08-12 |
| 4 | 3 | 2019-08-24 | 2019-08-24 |
| 5 | 3 | 2019-08-21 | 2019-08-22 |
| 6 | 2 | 2019-08-11 | 2019-08-13 |
| 7 | 4 | 2019-08-09 | 2019-08-09 |
+-------------+-------------+------------+-----------------------------+
Output:
103
+----------------------+
| immediate_percentage |
+----------------------+
| 50.00 |
+----------------------+
Explanation:
Code
SELECT
FROM
Delivery
WHERE
(customer_id, order_date)
IN
(SELECT
FROM
Delivery
GROUP BY
customer_id
);
104
References:
https://datalemur.com/
https://leetcode.com/
https://medium.com/nerd-for-tech/all-windows-functions-in-sql-6b4da1cfedd7
https://medium.com/@pradeepchandrareddy95/top-10-frequently-asked-sql-interview-
questions-f15a967c8656
https://medium.com/womenintechnology/sql-interview-questions-you-must-know-part-
1-630af3cc270c
https://medium.com/womenintechnology/scenario-based-sql-interview-questions-you-
must-know-part-2-f7a8c32f4f3d
https://medium.com/womenintechnology/sql-queries-you-must-practice-for-your-next-
interview-part-3-49711a131f7d
About Newton School
Founded by Nishant Chandra and Siddharth Maheshwari in 2019, Newton School is an ed-tech platform
that is building a futuristic online university to provide a highly immersive and interactive learning path
to millions of students and enable them to tap into new-age tech opportunities.
Newton School has placed over 2,500 aspirants in over 800 companies including Google, Target, Epsilon,
Jio, Lenskart, Razorpay, Flipkart, Zomato, Deloitte, Meesho and Target in a little over two years.
The problem
In India, more than a million college graduates fail to get relevant employment opportunities every year,
and yet there are thousands of companies struggling to find talent. Newton School’s learning platform
aims to bridge this gap.
Out of the 42,343 colleges that India has as on 2020, 60.56% are in rural areas, and the majority of the
remaining colleges are in Tier 2 and Tier 3 cities. This creates a huge gap in career opportunities in the
industry for students from these colleges due to the lack of resources, placement help, lack of industry
skills, as well as the acute shortage of jobs in the country.
The Solution
Newton School’s strength lies in offering an extraordinarily relevant and rigorous pedagogy that brings
world-class career opportunities to anyone from any part of the country. The organisation plans to
rapidly scale up and place 10,000+ students by the end of 2022.
While Newton School is building a neo-university, it is also redirecting education towards a skill-oriented
paradigm, wherein leading organisations and startups would be able to hire the right kind of talent in
multiple organisational layers. With Newton School’s students already earning a cumulative salary of
100+ crores, Newton School will be able to en-skill and up-skill millions of tech careers and bring the
conversation of employability to the podium of the world.