Icon New game New game

Mastering SQL CTEs

Fill in the Blanks

Drills to master SQL Common Table Expressions

Download the paper version to play

0 times made

Created by

United States

Top 10 results

There are still no results for this game. Be the first to stay in the ranking! to identify yourself.
Make your own free game from our game creator
Compete against your friends to see who gets the best score in this game

Top Games

  1. time
    score
  1. time
    score
time
score
time
score
 
game-icon

Fill in the Blanks

Mastering SQL CTEsOnline version

Drills to master SQL Common Table Expressions

by Good Sam
1

SELECT EmployeeHierarchy e.manager_id e EmployeeHierarchy 0 eh AS e.manager_id WHERE EmployeeHierarchy level WITH NULL SELECT ON id eh.level + 1 FROM id e.name name AS INNER ALL FROM JOIN employees manager_id FROM IS manager_id RECURSIVE SELECT e.id level name eh.id UNION employees

Problem 1 : Recursive Employee Hierarchy
Question : For a table employees ( id INT , name VARCHAR , manager_id INT ) , write a SQL query using a CTE to list all employees along with their level in the hierarchy ( 0 for the top manager , 1 for their direct reports , etc . ) .

Solution :



WITH RECURSIVE EmployeeHierarchy AS (
SELECT id , name , manager_id , 0 AS level
FROM employees
WHERE manager_id IS NULL
UNION ALL
SELECT e . id , e . name , e . manager_id , eh . level + 1
FROM employees e
INNER JOIN EmployeeHierarchy eh ON e . manager_id = eh . id
)
SELECT id , name , level
FROM EmployeeHierarchy ;


(
, , ,



, , ,

=
)
, ,
;


Explanation : This recursive CTE starts with the top - level manager ( where manager_id is null ) and recursively joins to its own defined result set to navigate down the employee hierarchy , incrementing the level by one with each recursion .

2

e.id = ts.emp_id total_sales JOIN BY SELECT e.name ON COALESCE LEFT GROUP sale_amount emp_id emp_id e FROM ts AS 0 WITH FROM AS TotalSales SUM SELECT TotalSales AS total_sales employees sales ts total_sales

Problem 2 : Summarizing Sales
Question : Calculate the total sales for each employee , assuming tables employees ( id , name ) and sales ( emp_id , sale_amount ) .

Solution :

WITH TotalSales AS (
SELECT emp_id , SUM ( sale_amount ) AS total_sales
FROM sales
GROUP BY emp_id
)
SELECT e . name , COALESCE ( ts . total_sales , 0 ) AS total_sales
FROM employees e
LEFT JOIN TotalSales ts ON e . id = ts . emp_id ;






(
, ( )


)
, ( . , )

;

Explanation : The CTE TotalSales calculates the total sales per employee . The main query then joins this CTE with the employees table to display all employees , including those with no sales ( using COALESCE to handle NULLs ) .

3

JOIN SUM WITH AS SalesRank SELECT sales FROM FROM e BY rank SELECT SalesRank sr sale_amount ON e.name e.id = sr.emp_id ORDER emp_id BY emp_id RANK() OVER sr.rank GROUP DESC AS employees

Problem 3 : Ranking Sales by Employee
Question : Rank employees based on their total sales in descending order .

Solution :

(
, ( ( ) )


)
,

;










WITH SalesRank AS (
SELECT emp_id , RANK ( ) OVER ( ORDER BY SUM ( sale_amount ) DESC ) AS rank
FROM sales
GROUP BY emp_id
)
SELECT e . name , sr . rank
FROM employees e
JOIN SalesRank sr ON e . id = sr . emp_id ;
Explanation : The CTE SalesRank calculates the total sales for each employee and assigns a rank based on these totals . The main query joins this CTE with the employees table to list employees along with their sales rank .

4

AS total_sales total_sales AS AS MONTH WITH FROM sale_date FROM COALESCE month AS SELECT FROM AS GROUP month YEAR EXTRACT sale_date EXTRACT FROM MonthlySales sale_date 0 year BY FROM MONTH FROM EXTRACT previous_month_sales year sale_amount previous_month_sales MonthlyGrowth SUM YEAR sale_date total_sales total_sales AS BY month month year growth OVER MonthlyGrowth FROM LAG SELECT sales MonthlySales year ORDER EXTRACT total_sales AS SELECT

Problem 4 : Monthly Sales Analysis
Question : Analyze monthly sales growth by comparing current month's sales with the previous month .

Solution :


(

( ) ,
( ) ,
( )

( ) , ( )
) ,
(

,
,
,
( ) ( , )

)
, , , ( - , )
;









WITH MonthlySales AS (
SELECT
EXTRACT ( YEAR FROM sale_date ) AS year ,
EXTRACT ( MONTH FROM sale_date ) AS month ,
SUM ( sale_amount ) AS total_sales
FROM sales
GROUP BY EXTRACT ( YEAR FROM sale_date ) , EXTRACT ( MONTH FROM sale_date )
) ,
MonthlyGrowth AS (
SELECT
year ,
month ,
total_sales ,
LAG ( total_sales ) OVER ( ORDER BY year , month ) AS previous_month_sales
FROM MonthlySales
)
SELECT year , month , total_sales , COALESCE ( total_sales - previous_month_sales , 0 ) AS growth
FROM MonthlyGrowth ;
Explanation : Two CTEs are used here . MonthlySales calculates the total sales for each month . MonthlyGrowth then uses the LAG window function within the CTE to find the previous month's sales , and the main query calculates the growth by subtracting the previous month's sales from the current month's .

5

BY 3 e sales COUNT(*) > employees SELECT HAVING FROM emp_id EmployeeSalesCount GROUP AS EmployeeSalesCount sale_amount e.name ON e.id = esc.emp_id avg_sale_amount avg_sale_amount num_sales emp_id SELECT esc FROM JOIN esc AVG WITH COUNT(*) AS AS

Problem 5 : Filtered Aggregation
Question : Compute the average sales per employee only for those employees who made more than 3 sales .

Solution :

(
, , ( )



)
, .

;










WITH EmployeeSalesCount AS (
SELECT emp_id , COUNT ( * ) AS num_sales , AVG ( sale_amount ) AS avg_sale_amount
FROM sales
GROUP BY emp_id
HAVING COUNT ( * ) > 3
)
SELECT e . name , esc . avg_sale_amount
FROM employees e
JOIN EmployeeSalesCount esc ON e . id = esc . emp_id ;
Explanation : The CTE EmployeeSalesCount calculates the number of sales and average sale amount per employee , filtering to include only those with more than three sales . The main query then joins this CTE to the employees table to fetch the employee names and their average sales .

6

employees name LIKE 'J%' SELECT id EmployeeCTE WHERE WITH FROM EmployeeCTE FROM name AS SELECT

Problem 6 : Simple CTE
Question : Create a CTE that selects all employees from the employees table and then use it to select all employees whose name starts with 'J' .

Solution :

(
,

)
*

;








WITH EmployeeCTE AS (
SELECT id , name
FROM employees
)
SELECT *
FROM EmployeeCTE
WHERE name LIKE 'J%' ;
Explanation : This CTE , EmployeeCTE , acts as a temporary table containing all employee records . The main query then filters this CTE for employees whose names start with 'J' .

7

RECURSIVE 10 NumberSequence number 1 WHERE FROM SELECT number + 1 FROM NumberSequence UNION WITH AS number ALL SELECT < NumberSequence SELECT AS

Problem 7 : Recursive CTE
Question : Write a recursive CTE to generate a sequence of numbers from 1 to 10 .

Solution :


(





)
*
;









WITH RECURSIVE NumberSequence AS (
SELECT 1 AS number
UNION ALL
SELECT number + 1
FROM NumberSequence
WHERE number < 10
)
SELECT *
FROM NumberSequence ;
Explanation : The recursive CTE starts with a base case ( selecting the number 1 ) , then recursively adds 1 to the previous number until the number 10 is reached .

8

amount SELECT AS amount SUM WITH sale_date SalesCTE BY ORDER sales AS OVER SELECT FROM running_total SalesCTE FROM sale_date

Problem 8 : CTE for Running Total
Question : Use a CTE to calculate the running total of sales from the sales table .

Solution :

WITH SalesCTE AS (
SELECT sale_date , amount ,
SUM ( amount ) OVER ( ORDER BY sale_date ) AS running_total
FROM sales
)
SELECT *
FROM SalesCTE ;









(
, ,
( ) ( )

)
*
;
Explanation : The CTE calculates the running total of sales amounts , ordered by the sale date . The window function SUM ( ) is used with the OVER clause to accumulate the sales .

9

FROM orders order_id HighValueOrders WITH order_id 1000 WHERE SET status = 'High value' HighValueOrders FROM orders WHERE order_id IN SELECT UPDATE AS total_amount > SELECT

Problem 9 : CTE in UPDATE Statement
Question : Use a CTE to update the status of orders in the orders table where the total amount is greater than 1000 .

Solution :


WITH HighValueOrders AS (
SELECT order_id
FROM orders
WHERE total_amount > 1000
)
UPDATE orders
SET status = 'High value'
WHERE order_id IN ( SELECT order_id FROM HighValueOrders ) ;









(



)


( ) ;
Explanation : The CTE identifies orders with a total amount greater than 1000 . The main UPDATE query then uses this result to set the status of these orders .

10

SELECT FROM salary END SalaryCategories id THEN 50000 WHEN 100000 AS 50000 name AND category SELECT 'High' BETWEEN salary 'Medium' AS SalaryCategories 'Low' salary FROM ELSE THEN employees WITH CASE WHEN <

Problem 10 : CTE for Data Partitioning
Question : Partition the employees table into three categories based on salary : Low , Medium , and High . Use a CTE for classification .

Solution :

WITH SalaryCategories AS (
SELECT id , name , salary ,
CASE
WHEN salary < 50000 THEN 'Low'
WHEN salary BETWEEN 50000 AND 100000 THEN 'Medium'
ELSE 'High'
END AS category
FROM employees
)
SELECT *
FROM SalaryCategories ;










(
, , ,






)
*
;
Explanation : The CTE classifies each employee into a salary category based on their salary . The CASE statement is used for conditional logic within the CTE to assign categories .

educaplay suscripción