0% found this document useful (0 votes)
8 views

Complex Queries Using CTE & Pivoting

Copyright
© © All Rights Reserved
Available Formats
Download as PDF, TXT or read online on Scribd
0% found this document useful (0 votes)
8 views

Complex Queries Using CTE & Pivoting

Copyright
© © All Rights Reserved
Available Formats
Download as PDF, TXT or read online on Scribd
You are on page 1/ 6

11/24/24, 10:23 PM Complex queries using CTE & Pivoting

Complex queries using CTE &


Pivoting
Agenda:
1. Previous Session Practice Problems
2. Common Table Expressions(CTE)

1. Previous Session Practice Problems

CREATE TABLE transactions ( transaction_id SERIAL PRIMARY KEY,


customer_id INT, amount DECIMAL(10, 2), transaction_date DATE ); INSERT
INTO transactions (customer_id, amount, transaction_date) VALUES (101,
50.00, '2024-04-01'), (102, 75.00, '2024-04-01'), (103, 100.00, '2024-04-
02'), (103, 100.00, '2024-04-05'), (104, 25.00, '2024-04-02'), (101,
150.00, '2024-04-03'), (102, 120.00, '2024-04-03'), (103, 90.00, '2024-
04-04'), (104, 110.00, '2024-04-04'), (104, 110.00, '2024-04-05'), (104,
110.00, '2024-04-06'), (104, 110.00, '2024-04-07'), (104, 120.00, '2024-
04-08'), (104, 120.00, '2024-04-09');

Practice: Get the average days between two consecutive transactions for each
customer.

https://almabetter.notion.site/Complex-queries-using-CTE-Pivoting-1191a19a5617800691b6d8c761500557 1/6
11/24/24, 10:23 PM Complex queries using CTE & Pivoting

-- -- Note: Group by and Window function can't be used in one expression


---- Error ---- select customer_id, avg(transaction_date -
lag(transaction_date,1) over(partition by customer_id order by
transaction_date asc)) as day_diff from transactions group by customer_id
---- Error ----- select *, lag(transaction_date,1) over(partition by
customer_id order by transaction_date asc) as prev_trans_date,
(transaction_date - lag(transaction_date,1) over(partition by customer_id
order by transaction_date asc)) as day_diff from transactions select
customer_id,round(avg(day_diff)) as avg_day_diff from (select *,
lag(transaction_date,1) over(partition by customer_id order by
transaction_date asc) as prev_trans_date, (transaction_date -
lag(transaction_date,1) over(partition by customer_id order by
transaction_date asc)) as day_diff from transactions) where day_diff is
not null group by customer_id

Practice: Get the absolute deviation of the transaction amount for each customer
from their average value.

-- Deviation: Avg of amount - actual amount for each customer -- 9:35 PM


-- abs() select *, round(avg(amount) over(partition by customer_id)) as
avg_amount_by_customer, round(abs(amount - round(avg(amount)
over(partition by customer_id)))) as abs_deviation from transactions

Practice: Keep only details of each customer's first and second transactions.

https://almabetter.notion.site/Complex-queries-using-CTE-Pivoting-1191a19a5617800691b6d8c761500557 2/6
11/24/24, 10:23 PM Complex queries using CTE & Pivoting

-- order by :: Date or amount ? -- Error SELECT*, ROW_NUMBER() OVER


(partition by customer_id ORDER BY transaction_date) AS rn FROM
transactions where rn <=2; -- Error SELECT * from( SELECT *, ROW_NUMBER()
OVER (partition by customer_id ORDER BY transaction_date) AS rn FROM
transactions) where rn <=2;

with table1 as ( SELECT *, ROW_NUMBER() OVER (partition by customer_id


ORDER BY transaction_date) AS rn FROM transactions) select * from table1
where rn<=2

2. Common Table Expressions(CTE)


Common Table Expressions (CTEs) are a powerful tool in SQL that allows you to
define temporary result sets that can be referenced multiple times within a single
query. In this way, CTEs provide a more readable and manageable way to handle
complex queries that might otherwise be difficult to write or understand.

WITH table_name1 AS ( CTE_query ), table_name2 as ( CTE_query ) final


statement;

CREATE TABLE mining_production ( date DATE NOT NULL, mine_id INT NOT
NULL, mineral VARCHAR(50) NOT NULL, production_quantity INT NOT NULL );
INSERT INTO mining_production (date, mine_id, mineral,
production_quantity) VALUES ('2023-06-01', 1, 'Gold', 150), ('2023-06-
01', 2, 'Silver', 200), ('2023-06-01', 1, 'Copper', 300), ('2023-06-02',
1, 'Gold', 160), ('2023-06-02', 2, 'Silver', 180), ('2023-06-02', 1,
'Copper', 320), ('2023-06-03', 1, 'Gold', 170), ('2023-06-03', 2,
'Silver', 210), ('2023-06-03', 1, 'Copper', 310), ('2023-06-04', 1,
'Gold', 140), ('2023-06-04', 2, 'Silver', 220), ('2023-06-04', 1,
'Copper', 330);

https://almabetter.notion.site/Complex-queries-using-CTE-Pivoting-1191a19a5617800691b6d8c761500557 3/6
11/24/24, 10:23 PM Complex queries using CTE & Pivoting

Problem: Analyze Production Data

-- For each mineral, on each day, provide the daily total production, --
the average production of that mineral over all days, -- and indicate
whether the daily production is above or equal to/below -- the average
production. --

-- For each mineral, on each day, provide the daily total production,
SELECT date, mineral, SUM(production_quantity) AS daily_total FROM
mining_production GROUP BY date, mineral

-- the average production of that mineral over all days. SELECT mineral,
AVG(production_quantity) AS avg_production FROM mining_production GROUP
BY mineral -- and indicate whether the daily production is above or equal
to/below -- the average production. --

https://almabetter.notion.site/Complex-queries-using-CTE-Pivoting-1191a19a5617800691b6d8c761500557 4/6
11/24/24, 10:23 PM Complex queries using CTE & Pivoting

WITH total_production AS ( SELECT date, mineral, SUM(production_quantity)


AS daily_total FROM mining_production GROUP BY date, mineral ),
average_production AS ( SELECT mineral, AVG(production_quantity) AS
avg_production FROM mining_production GROUP BY mineral ) SELECT tp.date,
tp.mineral, tp.daily_total, round(ap.avg_production) as avg_production ,
CASE WHEN tp.daily_total > ap.avg_production THEN 'Above Average' ELSE
'Below or Equal to Average' END AS production_status FROM
total_production tp JOIN average_production ap ON tp.mineral = ap.mineral
ORDER BY tp.date, tp.mineral;

3. Take Home Assignment

Practice: Get the average days between two consecutive transactions for each
customer. (Solve this question using CTE , write subquery as temporary table)

CREATE TABLE transactions ( transaction_id SERIAL PRIMARY KEY,


customer_id INT, amount DECIMAL(10, 2), transaction_date DATE ); INSERT
INTO transactions (customer_id, amount, transaction_date) VALUES (101,
50.00, '2024-04-01'), (102, 75.00, '2024-04-01'), (103, 100.00, '2024-04-
02'), (103, 100.00, '2024-04-05'), (104, 25.00, '2024-04-02'), (101,
150.00, '2024-04-03'), (102, 120.00, '2024-04-03'), (103, 90.00, '2024-
04-04'), (104, 110.00, '2024-04-04'), (104, 110.00, '2024-04-05'), (104,
110.00, '2024-04-06'), (104, 110.00, '2024-04-07'), (104, 120.00, '2024-
04-08'), (104, 120.00, '2024-04-09');

https://almabetter.notion.site/Complex-queries-using-CTE-Pivoting-1191a19a5617800691b6d8c761500557 5/6
11/24/24, 10:23 PM Complex queries using CTE & Pivoting

https://almabetter.notion.site/Complex-queries-using-CTE-Pivoting-1191a19a5617800691b6d8c761500557 6/6

You might also like