0% found this document useful (0 votes)
174 views23 pages

SQL Query Solutions and Analysis

The document provides solutions to 17 multiple choice questions related to SQL. Key points covered include: - Using window functions like RANK(), ROW_NUMBER(), and PARTITION BY to analyze and group data in meaningful ways - The differences between window functions and aggregate functions - Using CASE statements and subqueries to conditionally return values - Finding average values, counts, and comparing columns to subquery results The questions cover a range of SQL topics like window functions, aggregation, subqueries, and joining data from multiple tables. The solutions demonstrate techniques for analyzing customer order histories, grading student scores, and more.

Uploaded by

Ram Pal
Copyright
© © All Rights Reserved
We take content rights seriously. If you suspect this is your content, claim it here.
Available Formats
Download as PDF, TXT or read online on Scribd
0% found this document useful (0 votes)
174 views23 pages

SQL Query Solutions and Analysis

The document provides solutions to 17 multiple choice questions related to SQL. Key points covered include: - Using window functions like RANK(), ROW_NUMBER(), and PARTITION BY to analyze and group data in meaningful ways - The differences between window functions and aggregate functions - Using CASE statements and subqueries to conditionally return values - Finding average values, counts, and comparing columns to subquery results The questions cover a range of SQL topics like window functions, aggregation, subqueries, and joining data from multiple tables. The solutions demonstrate techniques for analyzing customer order histories, grading student scores, and more.

Uploaded by

Ram Pal
Copyright
© © All Rights Reserved
We take content rights seriously. If you suspect this is your content, claim it here.
Available Formats
Download as PDF, TXT or read online on Scribd
You are on page 1/ 23

SOLUTION FOR THE TEST

Round 1
Q.1) Which of the following options will give correct output to find the Number of
Consecutive Days With Order ?
a) WITH groupings_by_date AS (
SELECT c.id,
c.first_name,
c.last_name,
RANK() OVER (PARTITION BY c.id ORDER BY o.order_date) AS row_number,
o.order_date,
EXTRACT(DAY FROM o.order_date) - RANK() OVER (PARTITION BY c.id ORDER BY
o.order_date) AS date_group
FROM customers c
JOIN orders o
ON c.id = o.customer_id
)

SELECT id,
first_name,
last_name,
COUNT(*) AS orders_in_row
FROM groupings_by_date
GROUP BY id, first_name, last_name, date_group;
b) WITH groupings_by_date AS (
SELECT c.id,
c.first_name,
c.last_name,
RANK() OVER (PARTITION BY c.id ORDER BY o.order_date) AS row_number,
o.order_date,
EXTRACT(DAY FROM o.order_date) - RANK() OVER (PARTITION BY c.id ORDER BY
o.order_date) AS date_group
FROM customers c
JOIN orders o
)

SELECT id,
first_name,
last_name,
COUNT(*) AS orders_in_row
FROM groupings_by_date;
c) WITH groupings_by_date AS (
SELECT c.id,
c.first_name,
1
SOLUTION FOR THE TEST

c.last_name,
RANK() OVER (PARTITION BY c.id ORDER BY o.order_date) AS row_number,
o.order_date,
EXTRACT(DAY FROM o.order_date) - RANK() OVER (PARTITION BY c.id ORDER BY
o.order_date) AS date_group
FROM customers c
JOIN orders o
ON c.id = o.customer_id
)

SELECT id,
first_name,
last_name
FROM groupings_by_date
GROUP BY id, first_name, last_name, date_group;
d) None of the mentioned

Ans: WITH groupings_by_date AS (


SELECT c.id,
c.first_name,
c.last_name,
RANK() OVER (PARTITION BY c.id ORDER BY o.order_date) AS row_number,
o.order_date,
EXTRACT(DAY FROM o.order_date) - RANK() OVER (PARTITION BY c.id ORDER
BY o.order_date) AS date_group
FROM customers c
JOIN orders o
ON c.id = o.customer_id
)

SELECT id,
first_name,
last_name,
COUNT(*) AS orders_in_row
FROM groupings_by_date
GROUP BY id, first_name, last_name, date_group;

Q.2) Which of the following options will give correct output to Find the Average Number
of Orders?
a) WITH orders_count AS (
SELECT customer_id,
COUNT(*) AS no_of_orders
FROM orders

2
SOLUTION FOR THE TEST

GROUP BY customer_id)

SELECT AVG(no_of_orders) AS avg_no_of_orders


FROM orders_count;
b) WITH orders_count AS (
SELECT customer_id,
COUNT(*) AS no_of_orders
FROM orders
)

SELECT AVG(no_of_orders) AS avg_no_of_orders


FROM orders_count;
c) WITH orders_count AS (
SELECT customer_id,
COUNT(*) AS no_of_orders
FROM orders
)

SELECT SUM(no_of_orders)
FROM orders_count;
d) None of the above

Ans: WITH orders_count AS (


SELECT customer_id,
COUNT(*) AS no_of_orders
FROM orders
GROUP BY customer_id)

SELECT AVG(no_of_orders) AS avg_no_of_orders


FROM orders_count;

Q.3) Consider a table "student_grades" . Which is the correct syntax to give each
student a grade sort the rows to have the highest grades on top. When score is 94 or
higher, the row will have the value of A. If the score is instead 90 or higher it will have
the value of A-, and so on.
a) SELECT *,
CASE
WHEN score >= 94 THEN "A"
WHEN score >= 90 THEN "A-"
WHEN score >= 87 THEN "B+"
WHEN score >= 83 THEN "B"
WHEN score >= 80 THEN "B-"
WHEN score >= 77 THEN "C+"

3
SOLUTION FOR THE TEST

WHEN score >= 73 THEN "C"


WHEN score >= 70 THEN "C-"
WHEN score >= 67 THEN "D+"
WHEN score >= 60 THEN "D"
ELSE "F"
END AS grade
FROM students_grades;
b) SELECT name,
CASE
WHEN score >= 94 THEN "A"
WHEN score >= 90 THEN "A-"
WHEN score >= 87 THEN "B+"
WHEN score >= 83 THEN "B"
WHEN score >= 80 THEN "B-"
WHEN score >= 77 THEN "C+"
WHEN score >= 73 THEN "C"
WHEN score >= 70 THEN "C-"
WHEN score >= 67 THEN "D+"
WHEN score >= 60 THEN "D"
ELSE "F"
END AS grade
FROM students_grades
ORDER BY score DESC;
c) SELECT name,
CASE
WHEN score >= 94 THEN "A"
WHEN score >= 90 THEN "A-"
WHEN score >= 87 THEN "B+"
WHEN score >= 83 THEN "B"
WHEN score >= 80 THEN "B-"
WHEN score >= 77 THEN "C+"
WHEN score >= 73 THEN "C"
WHEN score >= 70 THEN "C-"
WHEN score >= 67 THEN "D+"
WHEN score >= 60 THEN "D"
ELSE "F"
END AS grade
FROM students_grades
ORDER BY score ;
d) None of the mentioned

Ans: SELECT name,


CASE

4
SOLUTION FOR THE TEST

WHEN score >= 94 THEN "A"


WHEN score >= 90 THEN "A-"
WHEN score >= 87 THEN "B+"
WHEN score >= 83 THEN "B"
WHEN score >= 80 THEN "B-"
WHEN score >= 77 THEN "C+"
WHEN score >= 73 THEN "C"
WHEN score >= 70 THEN "C-"
WHEN score >= 67 THEN "D+"
WHEN score >= 60 THEN "D"
ELSE "F"
END AS grade
FROM students_grades
ORDER BY score DESC;

Q.4) Examine the following SQL statement. What will be displayed in the query if the
artistID is 14?
"SELECT ALBUM_TITLE,
CASE ARTIST_ID WHEN 14 THEN 'JOURNEY'
WHEN 27 THEN 'MEAT LOAF'
ELSE 'NOT FOUND'
END
FROM TBL_ARTIST;
a) JOURNEY
b) MEAT LOAF
c) AN ERROR IS RETURNED
d) NULL
Ans: AN ERROR IS RETURNED

Q.5) Whenever a sub query appears in SQL, it is enclosed within ___________ and
placed to the _____ of the SQL operators.
a) Brackets, Left
b) Brackets, Right
c) Parenthesis, Left
d) Parenthesis, Right
Ans: Parenthesis, Right

Q.6) Which of the following clause cannot be used in SQL sub queries?
a) GROUP BY
b) ORDER BY
c) DELETE
d) FROM
Ans: ORDER BY

5
SOLUTION FOR THE TEST

Q.7) The _________ operator cannot be used with the sub query, but within it.
a) IN
b) INTO
c) BETWEEN
d) JOIN
Ans: BETWEEN

Q.8) Which of the following statements are False regarding subqueries?


a) Only two subqueries can be placed at one level
b) A subquery can appear on either side of a comparison operator
c) Both A and B
d) None of the above
Ans: Only two subqueries can be placed at one level

Q.9) Which of the following is used to find all courses taught in both the Fall 2009
semester and in the Spring 2010 semester .
a) SELECT course id
FROM SECTION AS S
WHERE semester = ’Fall’ AND YEAR= 2009 AND
EXISTS (SELECT *
FROM SECTION AS T
WHERE semester = ’Spring’ AND YEAR= 2010 AND
S.course id= T.course id);
b) SELECT name
FROM instructor
WHERE salary > SOME (SELECT salary
FROM instructor
WHERE dept name = ’Biology’);
c) SELECT COUNT (DISTINCT ID)
FROM takes
WHERE (course id, sec id, semester, YEAR) IN (SELECT course id, sec id, semester, YEAR
FROM teaches
WHERE teaches.ID= 10101);
d) (SELECT course id
FROM SECTION
WHERE semester = ’Spring’ AND YEAR= 2010)
Ans: SELECT course id
FROM SECTION AS S
WHERE semester = ’Fall’ AND YEAR= 2009 AND
EXISTS (SELECT *
FROM SECTION AS T
WHERE semester = ’Spring’ AND YEAR= 2010 AND
S.course id= T.course id);

6
SOLUTION FOR THE TEST

Q.10) Consider the below tables :


Table1 : Salesman (salesman_id, name, city, commision)
Table2 : Orders (ord_no, purch_amt, ord_date, customer_id, salesman_id)
which is the correct SQL query to find the order values greater than the average order
value of 10th October 2012. Return ord_no, purch_amt, ord_date, customer_id,
salesman_id.
a) SELECT *
FROM orders
HAVING purch_amt >
(SELECT AVG(purch_amt)
FROM orders
HAVING ord_date ='10/10/2012');
b) SELECT *
FROM orders
WHERE purch_amt >
(SELECT AVG(purch_amt)
FROM orders
WHERE ord_date ='10/10/2012');
c) SELECT *
FROM orders
HAVING purch_amt >
(SELECT AVG(purch_amt)
FROM orders
WHERE ord_date ='10/10/2012');
d) SELECT *
FROM orders
WHERE purch_amt >
(SELECT AVG(purch_amt)
FROM orders
HAVING ord_date ='10/10/2012');
Ans: SELECT *
FROM orders
WHERE purch_amt >
(SELECT AVG(purch_amt)
FROM orders
WHERE ord_date ='10/10/2012');

Q.11) Which of the following is a set function?


a) RANK
b) NTILE
c) Window
d) All of the mentioned
Ans: All of the mentioned

7
SOLUTION FOR THE TEST

Q.12) Fill in the blank: SELECT SUM(qty) __________(PARTITION BY EmpID) AS EmpQty


a) ON
b) FOR
c) OVER
d) WINDOW
Ans: OVER

Q.13) To narrow a window function's application to a subgroup within a data set, use
__________.
a) OVER
b) SUBGROUP
c) PARTITION BY
d) SECTION
Ans: PARTITION BY

Q.14) To narrow a window function's application to a subgroup within a data set, use
__________.
a) OVER
b) SUBGROUP
c) PARTITION BY
d) SECTION
Ans: PARTITION BY

Q.15) Which of the following options is not a window function?


a) ROW_NUMBER()
b) SUM()
c) LEAD()
d) RUN_TOTAL()
Ans: RUN_TOTAL()

Q.16) Which of the following is correct to describe the difference Between Window
Functions and Aggregate Functions.
a) aggregate functions group multiple rows into a single result row &
window functions produce a result for each individual row
b) aggregate functions produce a result for each individual row &
window functions group multiple rows into a single result row
c) Both 1 and 2
d) None of the mentioned
Ans: aggregate functions group multiple rows into a single result row &
window functions produce a result for each individual row

Q.17) If an order clause is included, but a window frame is not, which option will be the
default frame?

8
SOLUTION FOR THE TEST

a) There is not one - you must include a window frame


b) ROWS BETWEEN CURRENT ROW AND CURRENT ROW
c) RANGE BETWEEN UNBOUNDED PRECEDING AND CURRENT ROW
d) ROWS BETWEEN UNBOUNDED PRECEDING AND CURRENT ROW
Ans: RANGE BETWEEN UNBOUNDED PRECEDING AND CURRENT ROW

Q.18) Does a window function require the use of Group By?


a) YES
b) NO
c) Depends on the function
d) Depends on the number of impacted records
Ans: NO

Q.19) Select the term used to identify all rows after the current row in a partition.
a) FINAL ROW
b) UNBOUNDED FOLLOWING
c) END RANGE
d) CONTINUE TO END
Ans: UNBOUNDED FOLLOWING

Q.20) Which of the following is not a window function?


a) MIN()
b) AVG()
c) DIFF()
d) COUNT()
Ans: DIFF()

Q.21) Which of the clause is not mandatory?


a) OVER Clause
b) ORDER BY clause
c) PARTITION BY clause
d) All of the mentioned
Ans: PARTITION BY clause

Q.22) Which of the following function is an analytical window function?


a) LEAD
b) LAG
c) FIRST_VALUE
d) None of the mentioned
Ans: LEAD

Q.23) Which term is used to find the first value in a set of data?
a) BEGIN_AMT

9
SOLUTION FOR THE TEST

b) START_VALUE
c) START_AMT
d) FIRST_VALUE
Ans: FIRST_VALUE

Q.24) Which method for ranking records repeats a ranking when there is a tie and may
have a result set that is not consecutive?
a) RANK()
b) ROW_NUMBER()
c) DENSE_RANK()
d) NTILE()
Ans: RANK()

Q.25) Which of the following options is not a method for numbering or ranking records?
a) NUMBER()
b) RANK()
c) ROW_NUMBER()
d) DENSE_RANK()
Ans: NUMBER()

Q.26) Which function is used to determine which percentile a given row belongs to.
a) RANK()
b) DENSE_RANK()
c) NTILE()
d) ROW_NUMBER()
Ans: NTILE()

Q.27) Which function assigns a sequential integer number to each row in the query’s
result set.
a) RANK()
b) DENSE_RANK()
c) NTILE()
d) ROW_NUMBER()
Ans: ROW_NUMBER()

Q.28) Which window function can be used to fetch only even rows from a table
a) RANK()
b) DENSE_RANK()
c) NTILE()
d) ROW_NUMBER()
Ans: ROW_NUMBER()

Q.29) NTILE(3) will divide the data in ______ parts

10
SOLUTION FOR THE TEST

a) 2
b) 3
c) 1
d) 0
Ans: 3

Q.30) Point out the wrong statement.


a) RANK() returns the rank of each row of the result set of the partitioned column
b) DENSE_RANK() is same as RANK() function. Only difference is returns rank without gap
c) NTILE() distributes the column in an ordered partition into a specified number of groups
d) ROW_NUMBER() returns the serial number of the row order by specified column
Ans: NTILE() distributes the column in an ordered partition into a specified number of
groups

Q.31) Consider 3 tables :


1. category - category_id, name
2. film_category - film_id, category_id
3. film - film_id, title, description, release_year, language_id, length, rate
Which query will give correct output to compare each film length to the longest film in
its category
a) select title, name, length, MAX(length) over(PARTITION BY name) as max_length
from (
select f.title, c.name, f.length
from film f
inner join film_category fc
on fc.film_id = f.film_id
inner join catefory c
on c.category_id = fc.category_id
) x;
b) select title, name, length, MAX(length) over(order by name) as max_length
from (
select f.title, c.name, f.length
from film f
inner join film_category fc
on fc.film_id = f.film_id
inner join catefory c
on c.category_id = fc.category_id
) x;
c) select title, name, length, MAX(length) over(order by name) as max_length
from (
select f.title, c.name, f.length
from film f
inner join film_category fc

11
SOLUTION FOR THE TEST

on fc.film_id = f.film_id
group by 1,2,3
) x;
d) None of the mentioned
Ans: select title, name, length, MAX(length) over(PARTITION BY name) as max_length
from (
select f.title, c.name, f.length
from film f
inner join film_category fc
on fc.film_id = f.film_id
inner join catefory c
on c.category_id = fc.category_id
) x;

Q.32) Consider the following table:


1. Payment : payment_id, customer_id, staff_id, rental_id, amount, payment_ts
Which query can be used to calculate previous day's revenue?
a) WITH daily_revenue AS (
SELECT
DATE(payment_ts) date,
SUM(amount) revenue
FROM payment
GROUP BY DATE(payment_ts)
)
SELECT
date,
revenue,
LAG(revenue, 1) OVER (partition by date) prev_day_sales,
revenue *1.0/LAG(revenue,1) OVER (partition by date) AS dod
FROM daily_revenue
ORDER BY date;
b) WITH daily_revenue AS (
SELECT
DATE(payment_ts) date,
SUM(amount) revenue
FROM payment
GROUP BY DATE(payment_ts)
)
SELECT
date,
revenue,
LAG(revenue, 1) OVER (ORDER BY date) prev_day_sales,
revenue *1.0/LAG(revenue,1) OVER (ORDER BY date) AS dod

12
SOLUTION FOR THE TEST

FROM daily_revenue
ORDER BY date;
c) WITH daily_revenue AS (
SELECT
DATE(payment_ts) date,
SUM(amount) revenue
FROM payment
GROUP BY DATE(payment_ts)
)
SELECT
date,
revenue,
LEAD(revenue, 1) OVER (ORDER BY date) prev_day_sales,
revenue *1.0/LEAD(revenue,1) OVER (ORDER BY date) AS dod
FROM daily_revenue
ORDER BY date;
d) None of the mentioned
Ans: WITH daily_revenue AS (
SELECT
DATE(payment_ts) date,
SUM(amount) revenue
FROM payment
GROUP BY DATE(payment_ts)
)
SELECT
date,
revenue,
LAG(revenue, 1) OVER (ORDER BY date) prev_day_sales,
revenue *1.0/LAG(revenue,1) OVER (ORDER BY date) AS dod
FROM daily_revenue
ORDER BY date;

Q.33) Consider the following table :


1. ap_order - id, date, customer_id, merchant_id, order_channel, purchase_amount
Write a query that returns the third-order date for each customer. If a user ordered fewer
than 3 times, return NULL
a) WITH nth_order AS (
SELECT customer_id, date, ROW_NUMBER() OVER(GROUP BY customer_id )
order_index
FROM ap_order
)
SELECT customer_id, MAX(CASE WHEN order_index = 3 THEN date ELSE NULL END) AS
third_order_date

13
SOLUTION FOR THE TEST

FROM nth_order
GROUP BY customer_id
;
b) WITH nth_order AS (
SELECT customer_id, date, ROW_NUMBER() OVER(GROUP BY customer_id )
order_index
FROM ap_order
)
SELECT customer_id, MAX(order_index) AS third_order_date
FROM nth_order
GROUP BY customer_id
;
c) WITH nth_order AS (
SELECT customer_id, date, ROW_NUMBER() OVER(PARTITION BY customer_id ORDER
BY date) order_index
FROM ap_order
)
SELECT customer_id, MAX(CASE WHEN order_index = 3 THEN date ELSE NULL END) AS
third_order_date
FROM nth_order
GROUP BY customer_id
;
d) None of the mentioned
Ans: WITH nth_order AS (
SELECT customer_id, date, ROW_NUMBER() OVER(PARTITION BY customer_id
ORDER BY date) order_index
FROM ap_order
)
SELECT customer_id, MAX(CASE WHEN order_index = 3 THEN date ELSE NULL END)
AS third_order_date
FROM nth_order
GROUP BY customer_id
;

Q.34) Consider the following table :


1. ap_order - id, date, customer_id, merchant_id, order_channel, purchase_amount
Which query will return the number of customers who made their second purchase
within the same day of their first purchase
a) WITH nth_order AS (
SELECT customer_id, date, ROW_NUMBER() OVER(PARTITION BY customer_id ORDER
BY date) order_index
FROM ap_order
),

14
SOLUTION FOR THE TEST

first_two_orders AS (
SELECT customer_id,
MAX(CASE WHEN order_index = 1 THEN date ELSE NULL END) AS first_buy_date,
MAX(CASE WHEN order_index = 2 THEN date ELSE NULL END) AS second_buy_date
FROM nth_order
GROUP BY customer_id
)
SELECT COUNT(*)
FROM first_two_orders
WHERE first_buy_date - second_buy_date = 0
;

b) WITH nth_order AS (
SELECT customer_id, date, ROW_NUMBER() OVER(PARTITION BY customer_id )
order_index
FROM ap_order
),
first_two_orders AS (
SELECT customer_id,
RANK(CASE WHEN order_index = 1 THEN date ELSE NULL END) AS first_buy_date,
RANK(CASE WHEN order_index = 2 THEN date ELSE NULL END) AS second_buy_date
FROM nth_order
)
SELECT COUNT(*)
FROM first_two_orders
WHERE first_buy_date - second_buy_date = 0
;

c) WITH nth_order AS (
SELECT customer_id, date, ROW_NUMBER() OVER(PARTITION BY customer_id )
order_index
FROM ap_order
),
first_two_orders AS (
SELECT customer_id,
RANK(CASE WHEN order_index = 1 THEN date ELSE NULL END) AS first_buy_date,
RANK(CASE WHEN order_index = 2 THEN date ELSE NULL END) AS second_buy_date
FROM nth_order
)
SELECT COUNT(*)
FROM first_two_orders
;
d) None of the mentioned

15
SOLUTION FOR THE TEST

Ans: WITH nth_order AS (


SELECT customer_id, date, ROW_NUMBER() OVER(PARTITION BY customer_id
ORDER BY date) order_index
FROM ap_order
),
first_two_orders AS (
SELECT customer_id,
MAX(CASE WHEN order_index = 1 THEN date ELSE NULL END) AS first_buy_date,
MAX(CASE WHEN order_index = 2 THEN date ELSE NULL END) AS
second_buy_date
FROM nth_order
GROUP BY customer_id
)
SELECT COUNT(*)
FROM first_two_orders
WHERE first_buy_date - second_buy_date = 0
;

Q.35) Consider the following table :


1. emp - empno, ename, job, hiredate, sal
Which query will return the the rank according to the hire date of the employee and
order by the salary of the employee
a) select empno, ename, job, hiredate, sal,
rank()
over( partition by empno order by hiredate
)rnk

from emp
order by sal;
b) select empno, ename, job, hiredate, sal,
rank()
over( partition by hiredate
)rnk

from emp
order by sal;
c) select empno, ename, job, hiredate, sal,
rank()
over( order by hiredate
)rnk

from emp
order by sal;

16
SOLUTION FOR THE TEST

d) None of the mentioned


Ans: select empno, ename, job, hiredate, sal,
rank()
over( order by hiredate
)rnk

from emp
order by sal;

Q.36) Consider the following table :


1. user_transactions : transaction_id, product_id, spend, transaction_date
Which query is used to obtain the year-on-year growth rate for the total spend of each
product for each year.
a) WITH yearly_spend
AS (
SELECT
EXTRACT(YEAR FROM transaction_date) AS year,
product_id,
spend AS curr_year_spend
FROM user_transactions),
yearly_variance
AS (
SELECT
*,
LAG(curr_year_spend, 1) OVER (
PARTITION BY product_id
ORDER BY product_id, year) AS prev_year_spend
FROM yearly_spend)
SELECT
year,
product_id,
curr_year_spend,
prev_year_spend,
ROUND(100 * (curr_year_spend - prev_year_spend)/ prev_year_spend,2) AS yoy_rate
FROM yearly_variance;
b) WITH yearly_spend
AS (
SELECT
EXTRACT(YEAR FROM transaction_date) AS year,
product_id,
spend AS curr_year_spend
FROM user_transactions),
yearly_variance

17
SOLUTION FOR THE TEST

AS (
SELECT
*,
LAG(curr_year_spend, 1) OVER (
PARTITION BY product_id
ORDER BY product_id, year) AS prev_year_spend
FROM yearly_spend)
SELECT
year,
product_id,
curr_year_spend,
prev_year_spend,
ROUND(100 * (prev_year_spend) AS yoy_rate
FROM yearly_variance;
c) WITH yearly_spend
AS (
SELECT
EXTRACT(YEAR FROM transaction_date) AS year,
product_id,
spend AS curr_year_spend
FROM user_transactions),
yearly_variance
AS (
SELECT
*,
Row_number(curr_year_spend, 1) OVER (
PARTITION BY product_id
ORDER BY product_id, year) AS prev_year_spend
FROM yearly_spend)
SELECT
year,
product_id,
curr_year_spend,
prev_year_spend,
ROUND(100 * (curr_year_spend - prev_year_spend)/ prev_year_spend) AS yoy_rate
FROM yearly_variance;
d) None of the mentioned

Ans: WITH yearly_spend


AS (
SELECT
EXTRACT(YEAR FROM transaction_date) AS year,
product_id,

18
SOLUTION FOR THE TEST

spend AS curr_year_spend
FROM user_transactions),
yearly_variance
AS (
SELECT
*,
LAG(curr_year_spend, 1) OVER (
PARTITION BY product_id
ORDER BY product_id, year) AS prev_year_spend
FROM yearly_spend)
SELECT
year,
product_id,
curr_year_spend,
prev_year_spend,
ROUND(100 * (curr_year_spend - prev_year_spend)/ prev_year_spend,2) AS yoy_rate
FROM yearly_variance;

Q.37) Consider the following table :


1. transactions - transaction_id, type, amount, transaction_date
Which query will print the cumulative balance of the merchant account at the end of
each day, with the total balance reset back to zero at the end of the month. Output the
transaction date and cumulative balance.
a) WITH daily_balances
AS (
SELECT
DATE_TRUNC('day', transaction_date) AS transaction_day,
DATE_TRUNC('month', transaction_date) AS transaction_month,
SUM(CASE WHEN type = 'deposit' THEN amount
WHEN type = 'withdrawal' THEN -amount END) AS balance
FROM transactions
GROUP BY 1, 2
ORDER BY 1)
SELECT
transaction_day,
SUM(balance) OVER (ORDER BY transaction_day) AS balance
FROM daily_balances
ORDER BY transaction_day;
b) WITH daily_balances
AS (
SELECT
DATE_TRUNC('day', transaction_date) AS transaction_day,
DATE_TRUNC('month', transaction_date) AS transaction_month,

19
SOLUTION FOR THE TEST

SUM(CASE WHEN type = 'deposit' THEN amount


WHEN type = 'withdrawal' THEN -amount END) AS balance
FROM transactions
GROUP BY 1, 2
ORDER BY 1)
SELECT
transaction_day,
SUM(balance) OVER (
PARTITION BY transaction_month
ORDER BY transaction_day) AS balance
FROM daily_balances
ORDER BY transaction_day;
c) WITH daily_balances
AS (
SELECT
DATE_TRUNC('day', transaction_date) AS transaction_day,
DATE_TRUNC('month', transaction_date) AS transaction_month,
SUM(CASE WHEN type = 'deposit' THEN amount
WHEN type = 'withdrawal' THEN -amount END) AS balance
FROM transactions
GROUP BY 1, 2
ORDER BY 1)
SELECT
transaction_day,
SUM(balance) OVER (GROUP BY transaction_month ORDER BY transaction_day) AS
balance
FROM daily_balances
ORDER BY transaction_day;
d) None of the mentioned

Ans: WITH daily_balances


AS (
SELECT
DATE_TRUNC('day', transaction_date) AS transaction_day,
DATE_TRUNC('month', transaction_date) AS transaction_month,
SUM(CASE WHEN type = 'deposit' THEN amount
WHEN type = 'withdrawal' THEN -amount END) AS balance
FROM transactions
GROUP BY 1, 2
ORDER BY 1)
SELECT
transaction_day,
SUM(balance) OVER (

20
SOLUTION FOR THE TEST

PARTITION BY transaction_month
ORDER BY transaction_day) AS balance
FROM daily_balances
ORDER BY transaction_day;

Q.38) Consider the following table :


1. EmployeeSalaries - employee_id, salary, year
Which SQL query will return the employees who have received at least 3 year over year
raises ?
a) SELECT
a.employee_ID as employee_ID
FROM
(SELECT
employee_ID,
salary,
LEAD(salary) OVER (ORDER BY year DESC) as previous_year_sal
FROM Employee ) a
WHERE a.salary > a.previous_year_sal
GROUP BY employee_ID
HAVING count(*) = 2
b) SELECT
a.employee_ID as employee_ID
FROM
(SELECT
employee_ID,
salary,
LEAD(salary) OVER (ORDER BY year DESC) as previous_year_sal
FROM Employee ) a
WHERE a.salary > a.previous_year_sal
GROUP BY employee_ID
WHERE count(*) = 2
c) SELECT
a.employee_ID as employee_ID
FROM
(SELECT
employee_ID,
salary,
LEAD(salary) OVER (PARTITION BY employee_ID ORDER BY year DESC) as
previous_year_sal
FROM Employee ) a
WHERE a.salary > a.previous_year_sal
GROUP BY employee_ID
HAVING count(*) = 2

21
SOLUTION FOR THE TEST

d) None of the mentioned

Ans: SELECT
a.employee_ID as employee_ID
FROM
(SELECT
employee_ID,
salary,
LEAD(salary) OVER (PARTITION BY employee_ID ORDER BY year DESC) as
previous_year_sal
FROM Employee ) a
WHERE a.salary > a.previous_year_sal
GROUP BY employee_ID
HAVING count(*) = 2

Q.39) Consider the following table :


1. Scores - id, score
id is the primary key for this table.
Each row of this table contains the score of a game.
Choose the correct SQL query to rank the scores
a) SELECT Score AS score,
DENSE_RANK() OVER(ORDER BY Score DESC) AS Rnk
FROM Scores
b) SELECT Score AS score,
DENSE_RANK() OVER(PARTITION BY id ORDER BY Score DESC) AS Rnk
FROM Scores
c) SELECT Score AS score,
DENSE_RANK() OVER(PARTITION BY id ORDER BY Score) AS Rnk
FROM Scores
d) None of the mentioned
Ans: SELECT Score AS score,
DENSE_RANK() OVER(ORDER BY Score DESC) AS Rnk
FROM Scores

Q.40) Consider the following table :


1. emp - empno, ename, job, hiredate, sal
Which query will give rank according to the salary of the employee and order by the
salary of the employee in ascending order. Use Empno when sal is the same.
a) select empno, ename, job, hiredate, sal,
row_number() over(
order by sal, empno) as row_num,
rank()over(order by sal) as rnk,
dense_rank()

22
SOLUTION FOR THE TEST

over( order by sal


)as sal_dense_rnk

from emp
order by sal
;
b) select empno, ename, job, hiredate, sal,
row_number() over(
order by empno) as row_num,
rank()over(partition by empno order by sal) as rnk,
dense_rank()
over( order by sal
)as sal_dense_rnk

from emp
order by sal
;
c) select empno, ename, job, hiredate, sal,
row_number() over(partition by ename
order by sal, empno) as row_num,
rank()over(order by sal) as rnk,
dense_rank()
over( order by sal
)as sal_dense_rnk

from emp
order by sal
;
d) None of the mentioned

Ans: select empno, ename, job, hiredate, sal,


row_number() over(
order by sal, empno) as row_num,
rank()over(order by sal) as rnk,
dense_rank()
over( order by sal
)as sal_dense_rnk

from emp
order by sal
;

23

You might also like