0% found this document useful (0 votes)
10 views6 pages

Complex Queries Using CTE & Pivoting

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)
10 views6 pages

Complex Queries Using CTE & Pivoting

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