Podstawy baz danych 10
Baza
DVD Rental Service
CTE - Common Table Expression
SAMPLE
WITH cte_film AS (
SELECT
film_id,
title,
(CASE
WHEN length < 30 THEN 'Short'
WHEN length < 90 THEN 'Medium'
ELSE 'Long'
END) length
FROM
film
)
SELECT
film_id,
title,
length
FROM
cte_film
WHERE
length = 'Long'
ORDER BY
title;Recursive
CREATE TABLE employees (
employee_id serial PRIMARY KEY,
full_name VARCHAR NOT NULL,
manager_id INT
);
INSERT INTO employees (
employee_id,
full_name,
manager_id
)
VALUES
(1, 'Michael North', NULL),
(2, 'Megan Berry', 1),
(3, 'Sarah Berry', 1),
(4, 'Zoe Black', 1),
(5, 'Tim James', 1),
(6, 'Bella Tucker', 2),
(7, 'Ryan Metcalfe', 2),
(8, 'Max Mills', 2),
(9, 'Benjamin Glover', 2),
(10, 'Carolyn Henderson', 3),
(11, 'Nicola Kelly', 3),
(12, 'Alexandra Climo', 3),
(13, 'Dominic King', 3),
(14, 'Leonard Gray', 4),
(15, 'Eric Rampling', 4),
(16, 'Piers Paige', 7),
(17, 'Ryan Henderson', 7),
(18, 'Frank Tucker', 8),
(19, 'Nathan Ferguson', 8),
(20, 'Kevin Rampling', 8);
WITH RECURSIVE subordinates AS (
SELECT
employee_id,
manager_id,
full_name
FROM
employees
WHERE
employee_id = 2
UNION
SELECT
e.employee_id,
e.manager_id,
e.full_name
FROM
employees e
INNER JOIN subordinates s ON s.employee_id = e.manager_id
)
SELECT
*
FROM
subordinates;Window Function
select round(avg(rental_rate), 2)
from filmselect name, round(avg(rental_rate), 2)
from film
inner join film_category using(film_id)
inner join category using(category_id)
group by category_idselect
title,
name,
round(avg(rental_rate) OVER (partition by category_id), 2)
from film
inner join film_category using(film_id)
inner join category using(category_id)Functions
- aggregation functions
- AVG
- SUM
- MIN
- MAX
- COUNT
- dedicated window functions
select
title,
name,
rental_rate,
ROW_NUMBER() OVER(
PARTITION BY category_id
ORDER BY rental_rate
)
from film
inner join film_category using(film_id)
inner join category using(category_id)select
title,
name,
rental_rate,
RANK() OVER(
PARTITION BY category_id
ORDER BY rental_rate
)
from film
inner join film_category using(film_id)
inner join category using(category_id)select
title,
name,
rental_rate,
DENSE_RANK() OVER(
PARTITION BY category_id
ORDER BY rental_rate
)
from film
inner join film_category using(film_id)
inner join category using(category_id)select
DISTINCT name,
FIRST_VALUE (rental_rate) OVER(
PARTITION BY category_id
ORDER BY rental_rate
) as lowest_category_rental_rate
from film
inner join film_category using(film_id)
inner join category using(category_id)select
title,
name,
rental_rate,
LAG (rental_rate, 1) OVER(
PARTITION BY category_id
ORDER BY rental_rate
) as previous_price,
rental_rate - LAG (rental_rate, 1) OVER(
PARTITION BY category_id
ORDER BY rental_rate
) as diff_current_previous
from film
inner join film_category using(film_id)
inner join category using(category_id)select
title,
name,
rental_rate,
LEAD (rental_rate, 1) OVER(
PARTITION BY category_id
ORDER BY rental_rate
) as previous_price,
rental_rate - LEAD (rental_rate, 1) OVER(
PARTITION BY category_id
ORDER BY rental_rate
) as diff_current_previous
from film
inner join film_category using(film_id)
inner join category using(category_id)Import
COPY table(col1,col2)
FROM '/tmp/persons.csv' DELIMITER ',' CSV HEADER;COPY table(col1,col2)
FROM 'C:\tmp\persons.csv' DELIMITER ',' CSV HEADER;Ćwiczenia
- Przeczytać dokumentacje
- Uruchomic przykłady
- utworzyc tabele
old_employees(z taka sama schema jakemployees)- przepisac wszystkich (usunac ze starej, dodac do nowej) wyszystkich pracownikow, ktorch
manager_iddzieli sie przez 2 bez reszty (uzyc CTE)
- przepisac wszystkich (usunac ze starej, dodac do nowej) wyszystkich pracownikow, ktorch
- jaka jest roznica pomiedzy
WITH processed_payment AS (
UPDATE payment SET amount = amount * 1.01
RETURNING *
)
SELECT * FROM payment;a
WITH processed_payment AS (
UPDATE payment SET amount = amount * 1.01
RETURNING *
)
SELECT * FROM processed_payment;- zastap podzapytania z poprzednich cwiczen uzywajac CTE