Location via proxy:   [ UP ]  
[Report a bug]   [Manage cookies]                

Newton School Free SQL Handbook

Download as pdf or txt
Download as pdf or txt
You are on page 1of 108

SQL

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!

From another Newtonian,


Dhananjay Dadheech
0

Index
TOPICS Page

Order of execution 1

Window function Questions 2

Concept Based Questions 15

Must know Questions 28

Theoretical Questions 41

No Table only Query Based Questions 48

Competitive Questions (Easy, Medium and 53


Hard)
1

Order of execution of SQL Query

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

select empno, ename, job,


hiredate, sal,
rank()
over( order by hiredate
)rnk

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

select empno, ename, job,


hiredate, sal,
rank()
over( order by hiredate
)rnk

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

Here is the table structure

Q4. Show me distributions of Hollywood movie box office sales


using PERCENT_RANK, CUME_DIST, and NTILE (quartile, decile,
tertile, etc)

select name, gross_sales,


percent_rank()
over(
order by gross_sales
) as pct,
cume_dist()
over(order by gross_sales
5

) as cum_dist,ntile(4)
over(
order by gross_sales) as ntil
from movies;
Output:

Given a table as below:


Moons:
6

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:

Q6. I need departmental salaries running total by employee name


select deptno,empno,ename, job,sal,
sum(sal)
over(
partition by deptno
order by ename) as total
from emp
order by deptno, ename;
8

Here is the Table Structure:


Q7. I need a running total of total ocean coverage across the world,
largest to smallest.
select name, type, square_km,
sum(square_km) over ( order by square_km desc
rows between unbounded preceding and current row ) as tot from water;

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

Here is the table:

Q9. Calculate 6 months moving average of tweets per day.


10

select dte, tweet_millions,


avg(tweet_millions)
over(
order by dte
range between interval '6' month preceding and current row) as
average from tweets;

Here is the table:


11

Q10. Show me life expectancy throughout history in the UK


compared to 5 years on either side
select recorded_year, age,
first_value(age)
over(
order by recorded_year
range between interval '5' year preceding and interval '5' year
following
)as fv,
last_value(age)
over(
order by recorded_year
range between interval '5' year preceding and interval '5' year
following) as lv
from life_expectancy;

Here is the table:


12

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

Here is a table Structure


14

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

where lag_status is null


or lead_status is null
or lead_status <> status
order by order_id, from_date nulls first

Q13. Retrieve the order_id, customer_id, order_date, total_amount,


and the rank of each order based on the total order amount within
each month and year, ordered by order_date
SELECT order_id, customer_id, order_date, total_amount,
RANK() OVER (PARTITION BY EXTRACT(MONTH FROM order_date),
EXTRACT(YEAR FROM order_date) ORDER BY total_amount DESC) AS
order_rank
FROM orders
ORDER BY order_date;
15

Concept based questions

Employee Table -

CREATE TABLE emp (


emp_id INT,
emp_name VARCHAR(20),
department_id INT,
salary INT,
manager_id INT,
emp_age INT
);

INSERT INTO emp VALUES (1, 'Ankit', 100,10000, 4, 39);


INSERT INTO emp VALUES (2, 'Mohit', 100, 15000, 5, 48);
INSERT INTO emp VALUES (3, 'Vikas', 100, 10000,4,37);
INSERT INTO emp VALUES (4, 'Rohit', 100, 5000, 2, 16);
INSERT INTO emp VALUES (5, 'Mudit', 200, 12000, 6,55);
INSERT INTO emp VALUES (6, 'Agam', 200, 12000,2, 14);
INSERT INTO emp VALUES (7, 'Sanjay', 200, 9000, 2,13);
INSERT INTO emp VALUES (8, 'Ashish', 200,5000,2,12);
INSERT INTO emp VALUES (9, 'Mukesh',300,6000,6,51);
INSERT INTO emp VALUES (10, 'Rakesh',300,7000,6,50);

Departments Table -

CREATE TABLE department(

dept_id INT,
dept_name VARCHAR(10)
);

INSERT INTO department values(100,'Analytics');


INSERT INTO department values(300,'IT');

Orders Table -

CREATE TABLE orders(


customer_name CHAR(10),
order_date DATE,
16

order_amount INT,
customer_gender CHAR(6)
);

INSERT INTO orders values('Shilpa','2020-01-01',10000,'Female');


INSERT INTO orders values('Rahul','2020-01-02',12000,'Male');
INSERT INTO orders values('PRADEEP','2020-01-02',12000,'Female');
INSERT INTO orders values('Rohit','2020-01-03',15000,'Male');
INSERT INTO orders values('pradeep','2020-01-03',14000,'Female');

INSERT INTO department values(100,'Analytics');


INSERT INTO department values(300,'IT');

Q14. How do you find the duplicates in a given table?


SELECT
emp_id, COUNT(*)
FROM
emp
GROUP BY emp_id
HAVING COUNT(*) > 1;

• 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.

Q15. How to delete duplicates?


WITH cte AS (
SELECT *, ROW_NUMBER() OVER (PARTITION BY emp_id ORDER BY emp_id) AS rn
FROM emp
)
DELETE FROM cte WHERE rn > 1;

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.

Q16. Difference between union and union all?

1. UNION:

• The UNION operator removes duplicate rows from the


combined result set.

• It returns only distinct (unique) rows from the result sets of


the individual SELECT statements.

• The result set will contain only one occurrence of each


distinct row.

For example, if you have duplicate rows in both SELECT


statements, UNION will remove those duplicates from the final result.

SELECT * FROM emp


UNION
SELECT * FROM emp;

This query will return a result set with only distinct rows.

2. UNION ALL:

• The UNION ALL operator does not remove duplicate rows; it


includes all rows from the result sets of the individual
SELECT statements, including duplicates.
18

• It preserves all rows from the individual SELECT


statements, even if they are duplicates.

For example, if you have duplicate rows in both SELECT


statements, UNION ALL will include all occurrences of those rows in
the final result.

SELECT * FROM emp


UNION ALL
SELECT * FROM emp;

This query will return a result set that includes all rows, including
duplicates.

Q 17 — Difference between Rank, Row number, Dense Rank?

In SQL, RANK(), ROW_NUMBER(), and DENSE_RANK() are window functions


used to assign a rank or row number to rows in a result set based on
the specified ordering. However, they have different behaviors when
it comes to handling ties (rows with the same values). Let's go
through each of them:

RANK():

• RANK() assigns a unique rank to each distinct row in the


result set.

• If multiple rows have the same values and are assigned the
same rank, the next rank will skip the number of tied rows
19

and continue from there. In other words, it leaves gaps in


the ranking sequence for tied rows.

• It assigns the same rank to tied rows but doesn’t provide


unique row numbers.

SELECT
emp_id,
emp_name,
salary,
RANK() OVER(ORDER BY salary DESC) AS rnk
FROM
emp;

The query assigns ranks based on salary in descending order


using RANK(). If multiple employees have the same salary, they will
receive the same rank, and the next rank will skip the number of tied
employees.

ROW_NUMBER():

• ROW_NUMBER() assigns a unique row number to each row in


the result set.

• It doesn’t consider ties. If multiple rows have the same


values, they will still receive unique row numbers.

• It doesn’t leave gaps in the row numbering sequence.

SELECT
emp_id,
emp_name,
salary,
ROW_NUMBER() OVER(ORDER BY salary DESC) AS rn
20

FROM
emp;

The query assigns row numbers based on salary in descending order


using ROW_NUMBER(). It assigns a unique row number to each
employee, regardless of ties in salary.

DENSE_RANK():

• DENSE_RANK() assigns a unique rank to each distinct row in


the result set.

• 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.

• It assigns the same rank to tied rows but doesn’t provide


unique row numbers.

SELECT
emp_id,
emp_name,
salary,
DENSE_RANK() OVER(ORDER BY salary DESC) AS rn
FROM
emp;

The query assigns dense ranks based on salary in descending order


using DENSE_RANK(). If multiple employees have the same salary, they
will receive the same dense rank, and the next dense rank will not
skip any values.
21

Q18 — Employees who are not present in department table?

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.

2. FROM emp AS e: Specifies the source table for the query. It


aliases the emp table as e, which means you can refer to it
as e in the rest of the query.

3. LEFT JOIN: This is a type of join that combines rows from


the left table (emp) with rows from the right table
(department) based on a common column
(department_id in emp and dept_id in department). It includes
all rows from the left table, and only the matching rows
from the right table. If there's no match in the right table, it
includes NULL values for columns from the right table.

4. department AS d: Specifies the right table for the join and


aliases it as d, allowing you to refer to it as d in the query.

5. ON e.department_id = d.dept_id: This part of the query


defines the join condition, specifying that rows from
the emp table (e) should be matched with rows from
22

the department table (d) based on


the department_id and dept_id columns, respectively.

6. WHERE d.dept_id IS NULL;: This is the filter condition. It


specifies that you want to filter the result set to only include
rows where the dept_id column from the right table (d,
which is the department table) is NULL. This condition
effectively selects employees (e) who do not have a
matching department in the department table.
So, the overall result of this query will be a list of all columns for
employees (emp) who are not associated with any department
(where dept_id is NULL in the department table). These are the
employees who are not present in the department table.

Q18 — Second highest salary in each department?

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;

1. The inner query selects the emp_name, salary,


and department_id columns from the emp table.

2. The DENSE_RANK() function is used within the inner query. It


assigns a dense rank to each employee within their
respective departments based on their salaries.
23

The PARTITION BY clause divides the result set into


partitions, one for each unique department_id, and the ORDER
BY clause orders the rows within each partition by salary in
descending order.

3. The result of the inner query is aliased as a.

4. The outer query selects all columns (*) from the result of
the inner query (a).

5. The WHERE clause filters the result to include only rows


where the dense rank (rn) is equal to 2. This means it
selects employees who have the second-highest salary
within their respective departments.
So, the final result will be a list of employees with the second-highest
salary in each department.

Q19 : Find all the transactions done by customer named Pradeep.

SELECT *
FROM orders
WHERE UPPER(customer_name) = 'PRADEEP';

1. SELECT *: This part of the query specifies that you want to


select all columns (*) from the orders table in the result set.
It means you want to retrieve all the details of the
transactions.

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

3. WHERE UPPER(customer_name) = 'PRADEEP': This is the filtering


condition. It filters the result set to include only rows where
the customer_name column, after converting to uppercase
using the UPPER() function, is equal to 'PRADEEP' in
uppercase.

• UPPER(customer_name): This function converts


the customer_name column value to uppercase, ensuring a
case-insensitive comparison.

• 'PRADEEP': This is the value to which the


converted customer_name is compared. It's 'PRADEEP' in
uppercase, ensuring that the comparison is also case-
insensitive.

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.

Q20. : Self Join, manager salary > employee salary?

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

emp AS e2 ON e1.manager_id = e2.emp_id


WHERE e2.salary > e1.salary;

1. SELECT Clause:

• e1.emp_id, e1.emp_name, e2.emp_name AS manager_name,

e1.salary, e2.salary AS manager_salary: This part of the


query specifies which columns to include in the result set.

• e1.emp_id and e1.emp_name represent the ID and name of the


employee (the subordinate).

• e2.emp_name AS manager_name represents the name of the


employee's manager. The use of AS renames the column to
make it more descriptive.

• e1.salary is the salary of the employee.

• e2.salary AS manager_salary represents the salary of the


employee's manager. Again, AS is used to rename the
column.

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).

3. INNER JOIN Clause:


26

• INNER JOIN emp AS e2 ON e1.manager_id = e2.emp_id: This


clause performs a self-join on the emp table. It links
employees (subordinates) from e1 with their managers
from e2 based on the manager_id of the employee
(e1.manager_id) matching the emp_id of the manager
(e2.emp_id). In other words, it establishes the relationship
between employees and their managers within the same
table.

4. WHERE Clause:

• WHERE e2.salary > e1.salary;: This is the filtering


condition. It limits the result set to include only rows where
the salary of the manager (e2.salary) is greater than the
salary of the employee (e1.salary). This condition selects
employees whose managers earn more than they do.

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.

Q 21 : Update query to swap gender?

UPDATE orders
SET
customer_gender = CASE
WHEN customer_gender = 'Male' THEN 'Female'
27

WHEN customer_gender = 'Female' THEN 'Male'


END

1. UPDATE Clause:

• UPDATE orders: This part of the query specifies the table to


be updated, which is the orders table. It indicates that you
want to make changes to the data in this table.

2. SET Clause:

• SET customer_gender = CASE ... END: In this section, you


define the column you want to update (customer_gender)
and use a CASE statement to specify how the updates should
be performed.

3. CASE Statement:

• CASE WHEN customer_gender = 'Male' THEN 'Female' WHEN

customer_gender = 'Female' THEN 'Male' END:

This CASE statement is used to conditionally update


the customer_gender column. It operates as follows:

• When the current value of customer_gender is 'Male,' it


replaces it with 'Female.'

• When the current value of customer_gender is 'Female,' it


replaces it with 'Male.'
28

• For any other values in the customer_gender column, there


are no updates.

So, after running this UPDATE query, the values in


the customer_gender column of the orders table will be swapped. All
instances of 'Male' will be changed to 'Female,' and all instances of
'Female' will be changed to 'Male,' effectively swapping the genders
for those records while leaving other values in the column
unaffected.

Must Know Questions

Q22) What are different types of joins?

a) Inner Join: The INNER JOIN keyword selects records that have
matching values in both tables.

b) Left Join: The LEFT JOIN keyword returns all records


from the left table (table1), and the matched records from
29

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.

d) Self-Join: A self-JOIN is a regular join, but the table is joined


with itself. It can be used in scenario where in the table of the
employes I want to check which two employes are from same city.

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

Q23) What is the difference between cross join and


full/outer join?

Cross join don’t have a ON clause as everything is joined with


everything. WHEREAS, outer join is combination of left outer join
and right outer join. Outer join returns those rows that matches the
where clause and show null values for the rows, the ON conditions
isn’t met.

Q24) What is normalization? What are all the different


normalizations?

Normalization is the process of minimizing repetition and


dependency, by organizing fields and table of a database in a more
efficient way. It helps us to remove null, duplicate values and
enables efficient indexing.

Different types of normalization are:


31

1. 1NF — Removes duplicated attributes, Attribute data


should be atomic, and of same kind.

2. 2NF — Should be in 1NF and each non-key field is fully


dependent on the primary key.

3. 3NF — Should be in 2NF and all the non-key attributes


which are not dependent on the primary key should be
removed. All the attributes which are dependent on the
other non-key attributes should also be removed.

Q25) What is a View? Can I update data in the table using a


view?

A view is a virtual table which consists of a subset of data contained


in one or more real database table.

View is used when we need to give access to limited amount of data.


We can give permission to query a view for a table while denied
access to the original table. It acts as a security measure.

Yes, you can update data in the table using a view by using a simple
update statements.

Q26) What is an Index? What are all the different types of


indexes?
32

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

Clustered: It stores the data rows in a table in sorted


order. When a table has a clustered index, the table is called a
clustered table. If a table has no clustered index, its data rows are
stored in an unordered structure called a heap. You can only have
one clustered index on a table. And if you have a PK on the table it
automatically creates a clustered index.

Non-clustered: The non-clustered index is created to improve the


performance of frequently used queries not covered by clustered
index. Non-clustered index is built using the B-tree structure. The
data and the Non-clustered index are stored separately thus
claiming more storage space. You can have multiple non clustered
index on a table or view.

Following differences between clustered and non-clustered indexes.

1. There can be only one clustered index per table. However,


you can create multiple non-clustered indexes on a single
table.

2. Clustered indexes only sort tables. Therefore, they do not


consume extra storage. Non-clustered indexes are stored in
a separate place from the actual table claiming more
storage space.
33

3. Clustered indexes are faster than non-clustered indexes since they


don’t involve any extra lookup step

Q27) What is a Cursor?

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:

When you write a SELECT statement (that returns 1051 rows) to


fetch a bunch of data from that database the system receives the
statement and creates or uses an existing query plan, then it uses
indexes to locate the data on the disk, fetches the data in one foul
swoop and returns the data as a set.

But, cursor does it on a row by row basis, and it takes longer to do


so. This is because the set-based logic for which RDBMS systems
like SQL Server are optimized is completely broken and the entire
query process is repeated for each row.

Q28) What is a trigger?

A trigger is a special type of store d procedure that automatically


runs when an event occurs in the database server. There are 3 types
of triggers
34

a) DDL (Data Definition Language) triggers: We can create


triggers on DDL statements (like CREATE, ALTER, and DROP) and
certain system-defined stored procedures that perform DDL-like
operations. DDL trigger can be used to observe and control
actions performed on the server, and to audit these
operations.

b) DML (Data Modification Language) triggers: In SQL


Server we can create triggers on DML statements (like INSERT,
UPDATE, and DELETE) and stored procedures that perform DML-
like operations. These triggers are of two types:

· After Trigger: This type of trigger fires after SQL Server


finishes the execution of the action successfully that fired it. If
you insert record/row in a table then the trigger related/associated
with the insert event on this table will fire only after the row passes
all the constraints, like as primary key constraint, and some rules. If
the record/row insertion fails, SQL Server will not fire the
After Trigger.

· Instead of Trigger: An INSTEAD OF trigger is a trigger that


allows you to skip an INSERT, DELETE, or UPDATE statement to a
table or a view and execute other statements defined in the trigger
instead.

c) Logon Triggers: Logon triggers are a special type of trigger that


fire when LOGON event of SQL Server is raised. We can use these
35

triggers to audit and to track login activity or limit the number of


sessions for a specific login.

Q29) What is the difference between DELETE and


TRUNCATE commands?

Note: Truncate is a logged operation, it just doesn’t log removing


the records but it logs the page deallocation, whereas delete logs
every single record it removes from the table hence it takes longer to
execute.

Note: If we want to rollback a truncate, then we can write the


truncate inside the transaction and then rollback the transaction.

Q30) What are advantages and Disadvantages of Stored


Procedure?

Advantages:

Stored procedure can be used as a modular programming — means


create once, store and call for several times whenever required.
36

This facilitates faster execution instead of executing multiple


queries.

This reduces network traffic: The commands inside the SP are


executed as a single batch of code. This means only the call to
execute the procedure is sent over a network instead of every single
line of code being sent individually.

Disadvantage:

utilizes more memory in the database server

Q31) What are magic tables in SQL?

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.

These are the two Magic Tables:

1. Inserted

2. Deleted

Q32) What is function in database?


37

• It is a database object which is used for processing and


manipulating the data.

• It only supports SELECT and have READ-


ONLY Database Access

• We cannot use function to Insert/Update/Delete (DML


operations) records in the database table.

• It accepts only input parameters, do not have output


parameters. It returns single value.

Q33) What is stored procedure in database?

• A stored procedure groups one or more Transact-SQL


statements into a logical unit and is stored as an object in
the Database Server.

• When a stored procedure is called at the first time, SQL


Server creates an execution plan and stores it in the cache.
In the subsequent executions of the stored procedure, SQL
Server reuses the plan so that the stored procedure can
execute very fast with reliable performance.

Q34) Can we perform insert/ update/ delete operations


from function in database?

No, because functions only have READ-ONLY Database Access.

Q35) Why functions are useful in database?


38

• User-defined functions help to decompose a large program


into small segments

• makes program easy to understand, maintain and debug.

• Code can be reused by creating functions and execute them


when needed by calling that function.

Q36) What is the difference between Function and stored


procedures?

Q37) What is difference between primary key and unique


key?

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.

3. A Clustered index automatically created when a primary key is


defined whereas Unique key generates the non-clustered index.

Q38) Difference between varchar and nvarchar?


39

varchar- used for normal strings (not UNI-code) data types. It uses
1byte per character

nvarchar- used to hold UNI-code (like other languages German,


Chinese etc.) data as well as normal strings. use ’N’ before the UNI-
code data. It uses 2 bytes per character.

UNICODE: UNICODE is a uniform character encoding standard. A


UNICODE character uses multiple bytes to store the data in the
database. This means that using UNICODE it is possible to process
characters of various writing systems in one document. This could
be useful if you’re working with an international character set (for
example different languages).

Q39) What is the difference between Where and Having?

Q40) What is the difference between Union, Unionall?

The UNION command combines the result set of two or more


SELECT statements (only distinct values). The UNION
40

ALL command combines the result set of two or more SELECT


statements (allows duplicate values)

Q41) What is Coalesce() and IsNull()?

Coalesce: Returns the first non-null value passed into the param list.

SELECT COALESCE(NULL, NULL, NULL, ‘HelloSQL’, NULL,


‘sql.com’); returns ‘HelloSQL’.

IsNull(): Returns the specified value if the passed expression is null,


otherwise returns the expression.

SELECT ISNULL(NULL, ‘helloWorld’); returns ‘helloWorld’

Q42) How to find the name of the process that is blocking


database resource?

1) Activity Manager: You can use Activity Monitor to view


information about the current processes and locks held on SQL
Server resources.

2) Use stored procedure like sp_who2

3) Using DMVs
like: sys.dm_exec_requests/sys.dm_tran_locks/sys.dm_os
_waiting_tasks
41

Q43) How do I make sure that a column in Employee table


only accepts values greater than zero?

Ans: We can use the “CHECK” constraint while creating the column
in the table.

CREATE Table Employee(

id int,
Age int CHECK (Age>0)
)

Theoretical Questions

Q43) Let’s say I don’t permit you to create a foreign key


what would be an equivalent way of implementing the
foreign key? Let me give you an example.

Let’s say there is an employee and department table. Each


employee belongs to a department. Usually, you would
have a foreign key for the department id in the employee
table to make sure that each employee is admitted to the
correct department. Suppose you don’t have this
relationship and you are forbidden to create a foreign key,
what would you do? How would you implement this
scenario?
42

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.

Q44) What is the difference between a primary key and a


unique non-clustered index?

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:

If you have a Primary key on a column, it automatically creates a


clustered index. The clustered index stores the data rows in a table
in sorted order. If a table has no clustered index, its data rows are
stored in an unordered structure called a heap.

A unique non-clustered index is built using the B-tree structure.


The data and the Non-clustered index are stored separately thus
claiming more storage space. You can have multiple non-clustered
indexes on a table
43

Q45) What is the difference between a function and a


stored procedure except for the fact that a function
returns a value and a stored procedure doesn’t?

Ans: If you want to use transaction you must use a stored procedure
as transactions are not allowed in the function.

Another difference is that a function can be called inside a select


query but a stored procedure is not.

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

c) Suppose I have created GT1 and now I have disconnected my


connection. But you are still logged in. Will you see no table or an
empty table or all records in the table? Ans: I will still see all 5
records in the table.

d) Suppose now both of us have disconnected the connection and


you have later logged into the server. Still, will you see all the
records? Ans: Yes
44

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.

Q47) An architect designed a Stored Procedure in such a


way that it should have taken 15 mins to complete. But
when the junior developer wrote the script and ran the SP
it was taking 1 hour to complete. The junior developer
confirmed that this is an issue with the stored procedure
and the data and network are not issues here. The data is
not blocked and the infrastructure is not overloaded. How
would you help the junior developer to rectify the delay in
the stored procedure?

Ans: This is another way of asking how to improve the performance


of a stored procedure. There are three steps we can take to improve
the performance.

a) Remove any sub-queries from the Stored procedure.

b) Rebuilt the indexes on the table.

c) Avoid using temporary tables and functions.

Q48) You have a bank account table that has a column


Active. This column contains either 1 or 0. 1 means the
account is active and 0 means the account is inactive. Due
to some glitch, the values in the column got reversed. So all
45

the values with 0 were replaced by 1 and 1 was replaced by


0. What query would you run to make sure that the correct
values are updated? Note: you can not roll back.

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.

You can use if-else as well.

Q49) Let’s say I have a student and course table. One


student can enroll in multiple courses. One course can
have multiple students in it. How will you design the
database table for such a scenario? (Many to Many
relations) Hint: What is a junction Table?

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.

Q50) I have a parent-child relationship for product


categories and sub-categories. How will you design the
table structure? Example: Let’s say I have a category of
food that has subcategories like snacks and Meals.
Further, let’s say snacks also have subcategories like
appetizers and sweets. And sweets also have subcategories
like Milk-based and non-milk based. So here we have a
46

parent-child relationship. So how will you create such a


database structure? (Hierarchical database structure)

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.

I have implemented such a scenario in one of the projects where I


had to save folder structures in the database. If you want to get data
from such a database, you can do self-joins.

Q51) I have three transactions one is selected with ON


LOCK; one is selected with no lock and the third will
update. What will happen if I fire all three transactions
same time?

Let me know if you find a good answer to this. I am still looking.

Q52) I have an index on the column Stud_Name. I am


searching for a name using a wild card. My query is

a) select * from Stud_Details where Stud_Name like ‘A%’

b) select * from Stud_Details where Stud_Name like ‘%A’.

c) select * from Stud_Details where Stud_Name not like


‘A%’
47

In which case would the SQL server use the Index, that I
have created on Stud_Name?

I am still looking for a good explanation for this question. I also


added this question on stack overflow. You can check this link for a
detailed discussion of my stack overflow question. People are
divided on this question. Add comments in this post and we can
discuss what should be the right answer for this. But to the best of
my knowledge, I can say that for option (a) index will be used. For
options (b) and <c> index will not be used.

Q53) I want to delete a record from a table but I want to log


the details of this record in the audit table only after it has
successfully deleted. How can I add the records details in
the audit table after it has been deleted?

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

No Table only Query Based Questions

Q54) Find nth highest salary from the table?

select Top 1 Emp_Salary from (select distinct top N Emp_Salary


from EmployeeDetails order by Emp_Salary desc) as TopSalary
order by Emp_Salary asc

Without using Top/Limit:

SELECT Emp_Salary

FROM EmployeeDetails Emp1

WHERE N-1 = (

SELECT COUNT( DISTINCT ( Emp2.Emp_Salary ) )

FROM EmployeeDetails Emp2

WHERE Emp2.Emp_Salary > Emp1.Emp_Salary

)
49

Q55) In one table there are duplicated Id’s of an employee,


with salary in each row. Write a query to get the sum of all
the duplicate records salary in a separate column.

select Sum(EmpSalary) as salary from Employee Group by Id

Q56) How to remove duplicate records from database


having primary key column?

When PK is present

Delete From People where RowId NOT IN (select MIN(RowId)


FROM people GROUP BY [Name], [City], [State])

When PK is not present

Delete from EmployeeDetails where Emp_Id in (select Emp_id


from EmployeeDetails group by Emp_id, Emp_Name,
Emp_Gender, Emp_DeptId, Emp_Age, Emp_Salary having
COUNT(*)>1)

Q57)Find sum of total salary of male and female


employees.

select Emp_Gender, SUM(Emp_Salary)

from EmployeeDetails
50

group by Emp_Gender;

Q58)Write a SQL query to fetch project-wise count of


employees sorted by number of employees count in
descending order.

select Emp_DeptId,count(Emp_Id)as TotalEmployee from


EmployeeDetails

group by Emp_DeptId order by TotalEmployee desc

Q59) Write a query to fetch only the first name(string


before space) from the Emp_Name column of
EmployeeDetails table and last Name

select SUBSTRING(Emp_Name,0,CharIndex(‘ ‘,Emp_Name))as


FirstName from EmployeeDetails

SELECT LEFT(Emp_Name, CHARINDEX(‘ ‘,Emp_Name) — 1)as


FirstName FROM EmployeeDetails;

The LEFT() function extracts a number of characters from a string


(starting from left).

The SUBSTRING() function extracts some characters from a


string.
51

Q60) Write a query to fetch employee names and their


respective department records. Return employee details
even if the dept record is not present for the employee.

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.

select e.Emp_Name,d.Dept_Name from EmployeeDetails e left join


DepartmentDetails d on e.Emp_DeptId= d.Dept_Id

Q61) Write a SQL query to fetch all the Employees who are
also managers from EmployeeDetails table.

select * from EmployeeDetails e inner join EmployeeDetails d on


e.EmpId=d.ManagerId

Q62) Write a SQL query to fetch only odd rows from table.

The ROW_NUMBER() is a window function that assigns a


sequential integer to each row within a partition of a result set. The
row number starts with one for the first row in each partition.

select * from
52

select *,ROW_NUMBER() over(order by Emp_Id)as tRowNumber


from EmployeeDetails

) e where e.tRowNumber%2!=0

Q63) Find the Dept id Which has maximum strength of the


employees.

select Top 1 Emp_DeptId, Count(*) as NoOfEmployees from


EmployeeDetails group by Emp_DeptId order by NoOfEmployees
desc
53

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

+-------------+-------+

| Column Name | Type |

+-------------+-------+

| sale_id | int |

| product_id | int |

| year | int |

| quantity | int |

| price | int |

+-------------+-------+

(sale_id, year) is the primary key of this table.

product_id is a foreign key to Product table.

Each row of this table shows a sale on the product product_id in a certain year.

Note that the price is per unit.

Table: Product

+--------------+---------+

| Column Name | Type |

+--------------+---------+

| product_id | int |

| product_name | varchar |

+--------------+---------+

product_id is the primary key of this table.


54

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.

Return the resulting table in any order.

The query result format is in the following example.

Example 1:

Input:

Sales table:

+---------+------------+------+----------+-------+

| sale_id | product_id | year | quantity | price |

+---------+------------+------+----------+-------+

| 1 | 100 | 2008 | 10 | 5000 |

| 2 | 100 | 2009 | 12 | 5000 |

| 7 | 200 | 2011 | 15 | 9000 |

+---------+------------+------+----------+-------+

Product table:

+------------+--------------+

| product_id | product_name |

+------------+--------------+

| 100 | Nokia |

| 200 | Apple |

| 300 | Samsung |

+------------+--------------+

Output:

+--------------+-------+-------+

| product_name | year | price |

+--------------+-------+-------+

| Nokia | 2008 | 5000 |

| Nokia | 2009 | 5000 |


55

| Apple | 2011 | 9000 |

+--------------+-------+-------+

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

P.product_name, S.year, S.price

FROM

(SELECT DISTINCT product_id, year, price FROM Sales) S

INNER JOIN

Product AS P

USING (product_id);

Q2.

Write an SQL query that reports the total quantity sold for every product id.

Return the resulting table in any order.

The query result format is in the following example.

Output:

+--------------+----------------+

| product_id | total_quantity |

+--------------+----------------+

| 100 | 22 |

| 200 | 15 |

+--------------+----------------+
56

Code

SELECT product_id, SUM(quantity) AS total_quantity

FROM Sales

GROUP BY product_id

Q2.

Problem
Table: Activity

+--------------+---------+

| Column Name | Type |

+--------------+---------+

| player_id | int |

| device_id | int |

| event_date | date |

| games_played | int |

+--------------+---------+

(player_id, event_date) is the primary key of this table.

This table shows the activity of players of some games.

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.

Return the result table in any order.

The query result format is in the following example.

Example 1:
57

Input:

Activity table:

+-----------+-----------+------------+--------------+

| player_id | device_id | event_date | games_played |

+-----------+-----------+------------+--------------+

| 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

# Write your MySQL query statement below

SELECT player_id, event_date as first_login

FROM activity

WHERE (player_id, event_date)

IN (

SELECT player_id, MIN(event_date)

FROM activity
58

GROUP BY player_id

Q3.

Problem
Table: Customers

+---------------+---------+

| Column Name | Type |

+---------------+---------+

| customer_id | int |

| name | varchar |

| country | varchar |

+---------------+---------+

customer_id is the primary key for this table.

This table contains information about the customers in the company.

Table: Product

+---------------+---------+

| Column Name | Type |

+---------------+---------+

| product_id | int |

| description | varchar |

| price | int |

+---------------+---------+

product_id is the primary key for this table.

This table contains information on the products in the company.


59

price is the product cost.

Table: Orders

+---------------+---------+

| Column Name | Type |

+---------------+---------+

| order_id | int |

| customer_id | int |

| product_id | int |

| order_date | date |

| quantity | int |

+---------------+---------+

order_id is the primary key for this table.

This table contains information on customer orders.

customer_id is the id of the customer who bought "quantity" products with id


"product_id".

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.

Return the result table in any order.

The query result format is in the following example.

Example 1:

Input:

Customers table:

+--------------+-----------+-------------+

| customer_id | name | country |

+--------------+-----------+-------------+

| 1 | Winston | USA |

| 2 | Jonathan | Peru |

| 3 | Moustafa | Egypt |
60

+--------------+-----------+-------------+

Product table:

+--------------+-------------+-------------+

| product_id | description | price |

+--------------+-------------+-------------+

| 10 | LC Phone | 300 |

| 20 | LC T-Shirt | 10 |

| 30 | LC Book | 45 |

| 40 | LC Keychain | 2 |

+--------------+-------------+-------------+

Orders table:

+--------------+-------------+-------------+-------------+-----------+

| order_id | customer_id | product_id | order_date | quantity |

+--------------+-------------+-------------+-------------+-----------+

| 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:

Winston spent $300 (300 * 1) in June and $100 ( 10 * 1 + 45 * 2) in July 2020.


61

Jonathan spent $600 (300 * 2) in June and $20 ( 2 * 10) in July 2020.

Moustafa spent $110 (10 * 2 + 45 * 2) in June and $0 in July 2020.

Code

SELECT customer_id, name

FROM Customers JOIN Orders USING(customer_id)

JOIN Product USING(product_id)

GROUP BY customer_id

HAVING SUM(IF(LEFT(order_date, 7) = '2020-06', quantity, 0) * price) >= 100

AND SUM(IF(LEFT(order_date, 7) = '2020-07', quantity, 0) * price) >= 100

Q4.

Problem
Table: Products

+------------------+---------+

| Column Name | Type |

+------------------+---------+

| product_id | int |

| product_name | varchar |

| product_category | varchar |

+------------------+---------+

product_id is the primary key for this table.

This table contains data about the company's products.

Table: Orders
62

+---------------+---------+

| Column Name | Type |

+---------------+---------+

| product_id | int |

| order_date | date |

| unit | int |

+---------------+---------+

There is no primary key for this table. It may have duplicate rows.

product_id is a foreign key to the Products table.

unit is the number of products ordered in order_date.

Write an SQL query to get the names of products that have at least 100 units ordered
in February 2020 and their amount.

Return result table in any order.

The query result format is in the following example.

Example 1:

Input:

Products table:

+-------------+-----------------------+------------------+

| product_id | product_name | product_category |

+-------------+-----------------------+------------------+

| 1 | Leetcode Solutions | Book |

| 2 | Jewels of Stringology | Book |

| 3 | HP | Laptop |

| 4 | Lenovo | Laptop |

| 5 | Leetcode Kit | T-shirt |

+-------------+-----------------------+------------------+

Orders table:

+--------------+--------------+----------+

| product_id | order_date | unit |


63

+--------------+--------------+----------+

| 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 |

+--------------------+---------+

| Leetcode Solutions | 130 |

| Leetcode Kit | 100 |

+--------------------+---------+

Explanation:

Products with product_id = 1 is ordered in February a total of (60 + 70) = 130.

Products with product_id = 2 is ordered in February a total of 80.

Products with product_id = 3 is ordered in February a total of (2 + 3) = 5.

Products with product_id = 4 was not ordered in February 2020.

Products with product_id = 5 is ordered in February a total of (50 + 50) = 100.

Code
64

select product_name,sum(unit) as unit

from Products a

left join Orders b on a.product_id = b.product_id

where month(order_date) = 2 and year(order_date) = '2020'

group by a.product_id

Having unit >=100

Q5.

Problem
Table: Activity

+--------------+---------+

| Column Name | Type |

+--------------+---------+

| player_id | int |

| device_id | int |

| event_date | date |

| games_played | int |

+--------------+---------+

(player_id, event_date) is the primary key of this table.

This table shows the activity of players of some games.

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.

Return the result table in any order.

The query result format is in the following example.

Example 1:
65

Input:

Activity table:

+-----------+-----------+------------+--------------+

| player_id | device_id | event_date | games_played |

+-----------+-----------+------------+--------------+

| 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

# Write your MySQL query statement below

SELECT player_id, event_date as first_login

FROM activity

WHERE (player_id, event_date)

IN (

SELECT player_id, MIN(event_date)

FROM activity
66

GROUP BY player_id

Q6.

Problem
Table: Product

+--------------+---------+

| Column Name | Type |

+--------------+---------+

| product_id | int |

| product_name | varchar |

| unit_price | int |

+--------------+---------+

product_id is the primary key of this table.

Each row of this table indicates the name and the price of each product.

Table: Sales

+-------------+---------+

| Column Name | Type |

+-------------+---------+

| seller_id | int |

| product_id | int |

| buyer_id | int |

| sale_date | date |

| quantity | int |

| price | int |
67

+-------------+---------+

This table has no primary key, it can have repeated rows.

product_id is a foreign key to the Product table.

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.

Return the result table in any order.

The query result format is in the following example.

Example 1:

Input:

Product table:

+------------+--------------+------------+

| product_id | product_name | unit_price |

+------------+--------------+------------+

| 1 | S8 | 1000 |

| 2 | G4 | 800 |

| 3 | iPhone | 1400 |

+------------+--------------+------------+

Sales table:

+-----------+------------+----------+------------+----------+-------+

| seller_id | product_id | buyer_id | sale_date | quantity | price |

+-----------+------------+----------+------------+----------+-------+

| 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

HAVING SUM(PRICE) >= all (

SELECT SUM(PRICE)

FROM Sales

GROUP BY seller_id

Q7.

Problem
Table: SalesPerson

+-----------------+---------+

| Column Name | Type |

+-----------------+---------+

| sales_id | int |

| name | varchar |
69

| salary | int |

| commission_rate | int |

| hire_date | date |

+-----------------+---------+

sales_id is the primary key column for this table.

Each row of this table indicates the name and the ID of a salesperson alongside
their salary, commission rate, and hire date.

Table: Company

+————-+———+ | Column Name | Type | +————-+———+ | com_id | int | |


name | varchar | | city | varchar | +————-+———+ com_id is the primary key
column for this table. Each row of this table indicates the name and the ID of a
company and the city in which the company is located.

Table: Orders

+-------------+------+

| Column Name | Type |

+-------------+------+

| order_id | int |

| order_date | date |

| com_id | int |

| sales_id | int |

| amount | int |

+-------------+------+

order_id is the primary key column for this table.

com_id is a foreign key to com_id from the Company table.

sales_id is a foreign key to sales_id from the SalesPerson table.

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”.

Return the result table in any order.


70

The query result format is in the following example.

Example 1:

Input:

SalesPerson table:

+----------+------+--------+-----------------+------------+

| sales_id | name | salary | commission_rate | hire_date |

+----------+------+--------+-----------------+------------+

| 1 | John | 100000 | 6 | 4/1/2006 |

| 2 | Amy | 12000 | 5 | 5/1/2010 |

| 3 | Mark | 65000 | 12 | 12/25/2008 |

| 4 | Pam | 25000 | 25 | 1/1/2005 |

| 5 | Alex | 5000 | 10 | 2/3/2007 |

+----------+------+--------+-----------------+------------+

Company table:

+--------+--------+----------+

| com_id | name | city |

+--------+--------+----------+

| 1 | RED | Boston |

| 2 | ORANGE | New York |

| 3 | YELLOW | Boston |

| 4 | GREEN | Austin |

+--------+--------+----------+

Orders table:

+----------+------------+--------+----------+--------+

| order_id | order_date | com_id | sales_id | amount |

+----------+------------+--------+----------+--------+

| 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

s.sales_id NOT IN (SELECT

o.sales_id

FROM

orders o

LEFT JOIN

company c ON o.com_id = c.com_id

WHERE

c.name = 'RED')

;
72

Q8.

Problem
Table: NewYork

+-------------+------+

| Column Name | Type |

+-------------+------+

| student_id | int |

| score | int |

+-------------+------+

student_id is the primary key for this table.

Each row contains information about the score of one student from New York
University in an exam.

Table: California

+-------------+------+

| Column Name | Type |

+-------------+------+

| student_id | int |

| score | int |

+-------------+------+

student_id is the primary key for this table.

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.

An excellent student is a student that scored 90% or more in the exam.


73

Write an SQL query to report:

“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 |

+---------------------+

| New York University |

+---------------------+

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'

ELSE 'No Winner' END) AS WINNER

;
76

Q9.

Problem
Table: Weather

+---------------+---------+

| Column Name | Type |

+---------------+---------+

| 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).

Return the result table in any order.

The query result format is in the following example:

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

AND w1.Temperature > w2.Temperature

Q10.

Problem
Table: Department

+-------------+---------+

| Column Name | Type |

+-------------+---------+

| id | int |

| revenue | int |
78

| month | varchar |

+-------------+---------+

(id, month) is the primary key of this table.

The table has information about the revenue of each department per month.

The month has values in


["Jan","Feb","Mar","Apr","May","Jun","Jul","Aug","Sep","Oct","Nov","Dec"].

Write an SQL query to reformat the table such that there is a department id column
and a revenue column for each month.

Return the result table in any order.

The query result format is in the following example.

Example 1:

Input:

Department table:

+------+---------+-------+

| id | revenue | month |

+------+---------+-------+

| 1 | 8000 | Jan |

| 2 | 9000 | Jan |

| 3 | 10000 | Feb |

| 1 | 7000 | Feb |

| 1 | 6000 | Mar |

+------+---------+-------+

Output:

+------+-------------+-------------+-------------+-----+-------------+

| id | Jan_Revenue | Feb_Revenue | Mar_Revenue | ... | Dec_Revenue |

+------+-------------+-------------+-------------+-----+-------------+

| 1 | 8000 | 7000 | 6000 | ... | null |

| 2 | 9000 | null | null | ... | null |

| 3 | null | 10000 | null | ... | null |

+------+-------------+-------------+-------------+-----+-------------+
79

Explanation: The revenue from Apr to Dec is null.

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

+---------------+---------+

| Column Name | Type |

+---------------+---------+

| ad_id | int |

| user_id | int |

| action | enum |

+---------------+---------+

(ad_id, user_id) is the primary key for this table.

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.

The action column is an ENUM type of ('Clicked', 'Viewed', 'Ignored').

A company is running Ads and wants to calculate the performance of each Ad.

Performance of the Ad is measured using Click-Through Rate (CTR) where:

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.

The query result format is in the following example.


81

Example 1:

Input:

Ads table:

+-------+---------+---------+

| ad_id | user_id | action |

+-------+---------+---------+

| 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 = 1, ctr = (2/(2+1)) * 100 = 66.67

for ad_id = 2, ctr = (1/(1+2)) * 100 = 33.33

for ad_id = 3, ctr = (1/(1+1)) * 100 = 50.00


82

for ad_id = 5, ctr = 0.00, Note that ad_id = 5 has no clicks or views.

Note that we do not care about Ignored Ads.

Code

SELECT ad_id, IFNULL(ROUND(AVG(CASE WHEN action = 'Clicked' THEN 1

WHEN action = 'Viewed' THEN 0

ELSE NULL END)*100,2),0) AS ctr

FROM Ads

GROUP BY ad_id

ORDER BY ctr DESC, ad_id

Medium to hard Difficulty


Q12.

Problem
Table: Calls

+-------------+---------+

| Column Name | Type |

+-------------+---------+

| 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.

Return the result table in any order.

The query result format is in the following example.

Example 1:

Input:

Calls table:

+---------+-------+----------+

| from_id | to_id | duration |

+---------+-------+----------+

| 1 | 2 | 59 |

| 2 | 1 | 11 |

| 1 | 3 | 20 |

| 3 | 4 | 100 |

| 3 | 4 | 200 |

| 3 | 4 | 200 |

| 4 | 3 | 499 |

+---------+-------+----------+

Output:

+---------+---------+------------+----------------+

| person1 | person2 | call_count | total_duration |

+---------+---------+------------+----------------+

| 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 1 and 3 had 1 call and the total duration is 20.


84

Users 3 and 4 had 4 calls and the total duration is 999 (100 + 200 + 200 + 499).

Code

SELECT LEAST(from_id,to_id) as person1,

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

+---------------+---------+

| Column Name | Type |

+---------------+---------+

| customer_id | int |

| name | varchar |

+---------------+---------+

customer_id is the primary key for this table.

This table contains information about the customers.

Table: Orders

+---------------+---------+

| Column Name | Type |


85

+---------------+---------+

| order_id | int |

| order_date | date |

| customer_id | int |

| product_id | int |

+---------------+---------+

order_id is the primary key for this table.

This table contains information about the orders made by customer_id.

No customer will order the same product more than once in a single day.

Table: Products

+---------------+---------+

| Column Name | Type |

+---------------+---------+

| product_id | int |

| product_name | varchar |

| price | int |

+---------------+---------+

product_id is the primary key for this table.

This table contains information about the products.

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.

Return the result table in any order.

The query result format is in the following example.

Example 1:

Input:

Customers table:
86

+-------------+-------+

| customer_id | name |

+-------------+-------+

| 1 | Alice |

| 2 | Bob |

| 3 | Tom |

| 4 | Jerry |

| 5 | John |

+-------------+-------+

Orders table:

+----------+------------+-------------+------------+

| order_id | order_date | customer_id | product_id |

+----------+------------+-------------+------------+

| 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:

+------------+--------------+-------+

| product_id | product_name | price |

+------------+--------------+-------+

| 1 | keyboard | 120 |

| 2 | mouse | 80 |

| 3 | screen | 600 |
87

| 4 | hard disk | 450 |

+------------+--------------+-------+

Output:

+-------------+------------+--------------+

| customer_id | product_id | product_name |

+-------------+------------+--------------+

| 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

SELECT customer_id, product_id, product_name

FROM (

SELECT O.customer_id, O.product_id, P.product_name,

RANK() OVER (PARTITION BY customer_id ORDER BY COUNT(O.product_id) DESC) AS


rnk

FROM Orders O
88

JOIN Products P

ON O.product_id = P.product_id

GROUP BY customer_id, product_id

) temp

WHERE rnk = 1

ORDER BY customer_id, product_id

Q14.

Problem
Table: Customers

+---------------------+---------+

| Column Name | Type |

+---------------------+---------+

| customer_id | int |

| customer_name | varchar |

+---------------------+---------+

customer_id is the primary key for this table.

customer_name is the name of the customer.

Table: Orders

+---------------+---------+

| Column Name | Type |

+---------------+---------+

| order_id | int |

| customer_id | int |

| product_name | varchar |

+---------------+---------+
89

order_id is the primary key for this table.

customer_id is the id of the customer who bought the product "product_name".

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.

Return the result table ordered by customer_id.

The query result format is in the following example.

Example 1:

Input:

Customers table:

+-------------+---------------+

| customer_id | customer_name |

+-------------+---------------+

| 1 | Daniel |

| 2 | Diana |

| 3 | Elizabeth |

| 4 | Jhon |

+-------------+---------------+

Orders table:

+------------+--------------+---------------+

| order_id | customer_id | product_name |

+------------+--------------+---------------+

| 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

select a.customer_id, a.customer_name

from customers a , orders b

where a.customer_id = b.customer_id

group by a.customer_id

having sum(b.product_name="A") >0 and sum(b.product_name="B") > 0 and


sum(b.product_name="C")=0

Q15.

Problem
Table: Tree

+-------------+------+

| Column Name | Type |

+-------------+------+

| id | int |
91

| p_id | int |

+-------------+------+

id is the primary key column for this table.

Each row of this table contains information about the id of a node and the id of
its parent node in a tree.

The given structure is always a valid tree.

Each node in the tree can be one of three types:

• “Leaf”: if the node is a leaf node.


• “Root”: if the node is the root of the tree.
• 608-60”Inner”: If the node is neither a leaf node nor a root node. Write an
SQL query to report the type of each node in the tree.

Return the result table ordered by id in ascending order.

The query result format is in the following example.

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',

IF(atree.id IN (SELECT p_id FROM tree), 'Inner','Leaf')) Type

FROM

tree atree

ORDER BY atree.id

Q16.

Table: Seat

+-------------+---------+

| Column Name | Type |

+-------------+---------+

| id | int |

| student | varchar |

+-------------+---------+

id is the primary key column for this table.

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.

Return the result table ordered by id in ascending order.

The query result format is in the following example.

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

s1.id, COALESCE(s2.student, s1.student) AS student

FROM

seat s1

LEFT JOIN

seat s2 ON ((s1.id + 1) ^ 1) - 1 = s2.id

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

Select DISTINCT l1.Num AS ConsecutiveNums

FROM

Logs l1,

Logs l2,

Logs l3

WHERE l1.Id = l2.Id-1

AND l2.Id = l3.Id-1

AND l1.Num = l2.Num

AND l2.Num = l3.Num

Q18.

Problem
Table: Sales

+-------------+-------+

| Column Name | Type |

+-------------+-------+
97

| sale_id | int |

| product_id | int |

| user_id | int |

| quantity | int |

+-------------+-------+

sale_id is the primary key of this table.

product_id is a foreign key to Product table.

Each row of this table shows the ID of the product and the quantity purchased by a
user.

Table: Product

+-------------+------+

| Column Name | Type |

+-------------+------+

| product_id | int |

| price | int |

+-------------+------+

product_id is the primary key of this table.

Each row of this table indicates the price of each product.

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.

Return the resulting table in any order.

The query result format is in the following example.

Example 1:

Input:

Sales table:

+---------+------------+---------+----------+

| sale_id | product_id | user_id | quantity |

+---------+------------+---------+----------+

| 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:

- Spent 10 * 10 = 100 on product 1.

- Spent 7 * 15 = 105 on product 3.

User 101 spent the most money on product 3.

User 102:

- Spent (9 + 7) * 10 = 150 on product 1.

- Spent 6 * 25 = 150 on product 2.


99

- Spent 10 * 15 = 150 on product 3.

User 102 spent the most money on products 1, 2, and 3.

Code

-- Step 1: Calculate the total count of each product per user


WITH user_product_count AS (

SELECT user_id, product_id, SUM(quantity) as total_quantity

FROM Sales

GROUP BY user_id, product_id

),

-- Step 2: Rank the user purchases based on total amount spent on each product
user_spent AS (

SELECT user_id, product_id,

RANK() OVER (PARTITION BY user_id ORDER BY total_quantity * price DESC) as rk

FROM user_product_count s INNER JOIN Product p USING(product_id)

-- Step 3: Filter the Products user spend the most money


SELECT user_id, product_id

FROM user_spent

WHERE rk = 1

Q19.
100

Problem
Table: Customers

+---------------+---------+

| Column Name | Type |

+---------------+---------+

| customer_id | int |

| customer_name | varchar |

+---------------+---------+

customer_id is the primary key for this table.

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.

Notice that the maximum customer_id will not exceed 100.

Return the result table ordered by ids in ascending order.

The query result format is in the following example.

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

WITH RECURSIVE id_seq AS (

SELECT 1 as continued_id

UNION

SELECT continued_id + 1

FROM id_seq

WHERE continued_id < (SELECT MAX(customer_id) FROM Customers)

SELECT continued_id AS ids

FROM id_seq

WHERE continued_id NOT IN (SELECT customer_id FROM Customers)

Q20.

Problem

Table: Delivery

+-----------------------------+---------+

| Column Name | Type |

+-----------------------------+---------+
102

| delivery_id | int |

| customer_id | int |

| order_date | date |

| customer_pref_delivery_date | date |

+-----------------------------+---------+

delivery_id is the primary key of this table.

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.

The query result format is in the following example.

Example 1:

Input:

Delivery table:

+-------------+-------------+------------+-----------------------------+

| delivery_id | customer_id | order_date | customer_pref_delivery_date |

+-------------+-------------+------------+-----------------------------+

| 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:

The customer id 1 has a first order with delivery id 1 and it is scheduled.

The customer id 2 has a first order with delivery id 2 and it is immediate.

The customer id 3 has a first order with delivery id 5 and it is scheduled.

The customer id 4 has a first order with delivery id 7 and it is immediate.

Hence, half the customers have immediate first orders.

Code

SELECT

ROUND(100*SUM(CASE WHEN order_date = customer_pref_delivery_date THEN 1

ELSE 0 END)/ COUNT(distinct customer_id) ,2) AS immediate_percentage

FROM

Delivery

WHERE

(customer_id, order_date)

IN

(SELECT

customer_id, min(order_date) as min_date

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.

You might also like