--Создание схем windows_functions CREATE SCHEMA IF NOT EXISTS windows_functions --Выведем все данные из таблицы в схеме windows_functions: SELECT * FROM windows_functions.salary; --Кто получает больше всего в каждом департаменте? SELECT department, MAX(gross_salary) FROM windows_functions.salary GROUP BY department; --Кто получает больше всего в каждом департаменте (дополнительно вывести идентификатор сотрудника и его имя)? SELECT s.id, s.first_name, s.department, max_s.max_salary FROM windows_functions.salary AS s JOIN (SELECT s.department, MAX(s.gross_salary) AS max_salary FROM windows_functions.salary AS s GROUP BY s.department) AS max_s ON max_s.department = s.department AND max_s.max_salary = s.gross_salary; --Запрос выше только с помощью USING вместо ON SELECT s.id, s.first_name, s.department, max_s.gross_salary FROM windows_functions.salary AS s JOIN (SELECT s.department, MAX(s.gross_salary) AS gross_salary FROM windows_functions.salary AS s GROUP BY s.department) AS max_s USING (gross_salary, department); --Решить эту же задачу с помощью оконных функций SELECT s.id, s.first_name, s.department, s.gross_salary, MAX(s.gross_salary) OVER(PARTITION BY s.department) AS max_gross_salary FROM windows_functions.salary AS s; --Отфильтровать потенциальных кандидатов на сокращение выделив запрос в подзапрос: SELECT max_s.id, max_s.first_name, max_s.department, max_s.max_gross_salary FROM (SELECT s.id, s.first_name, s.department, s.gross_salary, MAX(s.gross_salary) OVER(PARTITION BY s.department) AS max_gross_salary FROM windows_functions.salary AS s) AS max_s WHERE max_s.max_gross_salary = max_s.gross_salary ORDER BY max_s.id; --Показать пропорцию зарплат в отделе относительно суммы всех зарплат в этом отделе, --а также относительно всего фонда оплаты труда WITH gross_by_departments AS (SELECT s.department, SUM(s.gross_salary) AS department_gross_salary FROM windows_functions.salary AS s GROUP BY s.department) SELECT s.id, s.first_name, s.department, s.gross_salary, ROUND(((s.gross_salary::numeric / gbd.department_gross_salary) * 100), 2) AS department_ratio, ROUND(((s.gross_salary::numeric / (SELECT SUM(s.gross_salary) FROM windows_functions.salary AS s)) * 100), 2) AS total_ratio FROM windows_functions.salary AS s JOIN gross_by_departments AS gbd USING(department) ORDER BY s.department, department_ratio DESC; --Решить эту же задачу с помощью оконных функций SELECT s.id, s.first_name, s.department, s.gross_salary, ROUND(((s.gross_salary::numeric / SUM(s.gross_salary) OVER(PARTITION BY s.department)) * 100), 2) AS department_ratio, ROUND(((s.gross_salary::numeric / SUM(s.gross_salary) OVER()) * 100), 2) AS total_ratio FROM windows_functions.salary AS s ORDER BY s.department, department_ratio DESC; --Вернуть имя сотрудника у которого самая высокая зарплата в департаменте используя оконные функции SELECT s.id, s.first_name, s.department, s.gross_salary, FIRST_VALUE(s.first_name) OVER(PARTITION BY s.department ORDER BY s.gross_salary DESC) AS highest_paid_employee FROM windows_functions.salary AS s; --Вернуть имя сотрудника у которого самая низкая зарплата в департаменте используя оконные функции SELECT s.id, s.first_name, s.department, s.gross_salary, LAST_VALUE(s.first_name) OVER(PARTITION BY s.department ORDER BY s.gross_salary DESC ROWS BETWEEN UNBOUNDED PRECEDING AND UNBOUNDED FOLLOWING) AS lowest_paid_employee FROM windows_functions.salary AS s; --Посмотреть какие данные хранятся в таблице social_media в схеме windows_functions SELECT * FROM windows_functions.social_media; --Вывести данные о сумме прироста последователей для аккаунта instagram за весь период SELECT username, SUM(change_in_followers) FROM windows_functions.social_media WHERE username = 'instagram' GROUP BY username; --Вывести столбцы месяц и количество последователей для аккаунта instagram, а также --добавьте еще один столбец running_total, который будет отображать нарастающую сумму последователей --из месяца в месяц в порядке возростания (используйте оконную функцию) SELECT month, change_in_followers, SUM(change_in_followers) OVER(ORDER BY month ASC) AS running_total FROM windows_functions.social_media WHERE username = 'instagram'; --Теперь найдем кумулятивное среднее, изменив функцию SUM на функцию AVG SELECT month, change_in_followers, AVG(change_in_followers) OVER(ORDER BY month ASC) AS running_avg FROM windows_functions.social_media WHERE username = 'instagram'; --Рассмотрим пример того как работает PARTITION BY в оконных функциях SELECT username, month, change_in_followers, SUM(change_in_followers) OVER(PARTITION BY username ORDER BY month ASC) AS running_total_followers_change, AVG(change_in_followers) OVER(PARTITION BY username ORDER BY month ASC) AS running_avg_followers_change FROM windows_functions.social_media; --Пример использования оконной функции FIRST_VALUE() - наименьшее количество постов по каждому пользователю за весь период: SELECT username, month, posts, FIRST_VALUE(posts) OVER (PARTITION BY username ORDER BY posts DESC) AS least_posts FROM windows_functions.social_media; --Пример использования оконной функции FIRST_VALUE() - наибольшее количество постов по каждому пользователю за весь период: SELECT: SELECT username, month, posts, FIRST_VALUE(posts) OVER (PARTITION BY username ORDER BY posts DESC) AS most_posts FROM windows_functions.social_media; --Пример использования оконной функции LAST_VALUE(): SELECT username, month, posts, LAST_VALUE(posts) OVER (PARTITION BY username ORDER BY posts RANGE BETWEEN UNBOUNDED PRECEDING AND UNBOUNDED FOLLOWING) FROM windows_functions.social_media; --Посмотреть какие данные хранятся в таблице streams в схеме windows_functions SELECT * FROM windows_functions.streams; --Пример использования оконной функции LAG: SELECT artist, week, streams_millions, LAG(streams_millions::text, 1, 'нет значения') OVER(ORDER BY week ASC) AS previous_week_streams FROM windows_functions.streams WHERE artist = 'Lady Gaga'; --Расчет изменения streams_millions от недели к недели с помощью оконной функции LAG для артиста 'Lady Gaga: SELECT artist, week, streams_millions, streams_millions - LAG(streams_millions, 1, streams_millions) OVER(ORDER BY week ASC) AS streams_millions_change FROM windows_functions.streams WHERE artist = 'Lady Gaga'; --Расчет изменения streams_millions и chart_position от недели к недели для всех артистов с помощью оконной функции LAG: SELECT artist, week, streams_millions, streams_millions - LAG(streams_millions, 1, streams_millions) OVER(PARTITION BY artist ORDER BY week ASC) AS streams_millions_change, chart_position, LAG(chart_position, 1, chart_position) OVER(PARTITION BY artist ORDER BY week ASC) - chart_position AS chart_position_change FROM windows_functions.streams; --Пример использования оконной функции LEAD: SELECT artist, week, streams_millions, LEAD(streams_millions, 1) OVER(PARTITION BY artist ORDER BY week ASC) AS next_week_streams, chart_position, LEAD(chart_position, 1) OVER(PARTITION BY artist ORDER BY week ASC) AS next_week_chart_position FROM windows_functions.streams; --Расчет изменения streams_millions и chart_position от недели к недели для всех артистов с помощью оконной функции LEAD: SELECT artist, week, streams_millions, LEAD(streams_millions, 1, streams_millions) OVER(PARTITION BY artist ORDER BY week ASC) - streams_millions AS streams_millions_change, chart_position, chart_position - LEAD(chart_position, 1, chart_position) OVER(PARTITION BY artist ORDER BY week ASC) AS chart_position_change FROM windows_functions.streams; --Пример использования оконной функции ROW_NUMBER: SELECT artist, week, streams_millions, ROW_NUMBER() OVER(ORDER BY streams_millions ASC) AS row_num FROM windows_functions.streams; --Пример использования оконной функции ROW_NUMBER c фильтрацией (вывод 30-ой строки): WITH our_rows AS (SELECT artist, week, streams_millions, ROW_NUMBER() OVER(ORDER BY streams_millions ASC) AS row_num FROM windows_functions.streams) SELECT * FROM our_rows WHERE row_num = 30; --Пример использования оконной функции ROW_NUMBER c фильтрацией (вывод с 1 по 10 строку): WITH our_rows AS (SELECT artist, week, streams_millions, ROW_NUMBER() OVER(ORDER BY streams_millions ASC) AS row_num FROM windows_functions.streams) SELECT * FROM our_rows WHERE row_num BETWEEN 1 AND 10; --Пример использования оконных функции RANK и DENSE_RANK: SELECT artist, week, streams_millions, RANK() OVER(ORDER BY streams_millions ASC) AS rank_result, DENSE_RANK() OVER(ORDER BY streams_millions ASC) AS dense_rank_result FROM windows_functions.streams; --Пример использования оконных функции RANK и DENSE_RANK с группировкой по неделям: SELECT artist, week, streams_millions, RANK() OVER(PARTITION BY week ORDER BY streams_millions ASC) AS rank_result, DENSE_RANK() OVER(PARTITION BY week ORDER BY streams_millions ASC) AS dense_rank_result FROM windows_functions.streams; --Пример использования оконной функции NTILE: SELECT artist, week, streams_millions, NTILE(5) OVER(ORDER BY streams_millions DESC) AS weekly_streams_group FROM windows_functions.streams; --Пример использования использования оконной функции NTILE с группировкой по неделям : SELECT artist, week, streams_millions, NTILE(4) OVER(PARTITION BY week ORDER BY streams_millions DESC) AS quartile FROM windows_functions.streams; --Посмотреть какие данные хранятся в таблице state_climate в схеме windows_functions SELECT * FROM windows_functions.state_climate; --Посмотрим как изменяется средняя температура с течением времени в каждом штате SELECT state, year, tempf, AVG(tempf) OVER(PARTITION BY state ORDER BY year) AS running_avg_tempf, tempc, AVG(tempc) OVER(PARTITION BY state ORDER BY year) AS running_avg_tempc FROM windows_functions.state_climate; --Найти самую низкую температуру по каждому штату SELECT state, year, tempf, FIRST_VALUE(tempf) OVER(PARTITION BY state ORDER BY tempf) AS lowest_tempf, tempc, FIRST_VALUE(tempc) OVER(PARTITION BY state ORDER BY tempc) AS lowest_tempc FROM windows_functions.state_climate; --Найти самую высокую температуру по каждому штату SELECT state, year, tempf, LAST_VALUE(tempf) OVER(PARTITION BY state ORDER BY tempf RANGE BETWEEN UNBOUNDED PRECEDING AND UNBOUNDED FOLLOWING) AS highest_tempf, tempc, LAST_VALUE(tempc) OVER(PARTITION BY state ORDER BY tempc RANGE BETWEEN UNBOUNDED PRECEDING AND UNBOUNDED FOLLOWING) AS highest_tempc FROM windows_functions.state_climate; --Посмотрим на сколько меняется температура каждый год в каждом штате SELECT state, year, tempf, tempf - LAG(tempf, 1, tempf) OVER(PARTITION BY state ORDER BY year) AS change_in_tempf, tempc, tempc - LAG(tempc, 1, tempc) OVER(PARTITION BY state ORDER BY year) AS change_in_tempc FROM windows_functions.state_climate; --Найти самую низкую температуру за всю историю SELECT state, year, tempf, RANK() OVER(ORDER BY tempf) AS coldest_rankf, tempc, RANK() OVER(ORDER BY tempc) AS coldest_rankc FROM windows_functions.state_climate; --Найти самую высокую температуру в разбивке по штатам SELECT state, year, tempf, RANK() OVER(PARTITION BY state ORDER BY tempf DESC) AS warmest_rankf, tempc, RANK() OVER(PARTITION BY state ORDER BY tempc DESC) AS warmest_rankc FROM windows_functions.state_climate; --Выведем среднегодовые температуры в квартилях и квантилях, а не в рейтингах для каждого штата SELECT state, year, tempf, NTILE(4) OVER(PARTITION BY state ORDER BY tempf) AS quartile_f, NTILE(5) OVER(PARTITION BY state ORDER BY tempf) AS quintile_c, tempc, NTILE(4) OVER(PARTITION BY state ORDER BY tempc) AS quartile_c, NTILE(5) OVER(PARTITION BY state ORDER BY tempc) AS quintile_c FROM windows_functions.state_climate; --Посмотреть какие данные хранятся в таблице summer_medals в схеме windows_functions SELECT * FROM windows_functions.summer_medals; --Присвоим номер каждой выбранной записи с помощью оконной функции ROW_NUMBER() SELECT athlete, event, ROW_NUMBER() OVER() AS row_number FROM windows_functions.summer_medals ORDER BY row_number ASC; --Найдем всех олимпийских чемпионов по теннису (мужчин и женщин отдельно), начиная с 2004 года, --и для каждого из них выяснить, кто был предыдущим чемпионом. --Табличное выражение ищет теннисных чемпионов и выбирает нужные столбцы WITH tennis_gold AS (SELECT athlete, gender, year, country FROM windows_functions.summer_medals WHERE year >= 2004 AND sport = 'Tennis' AND event = 'singles' AND medal = 'Gold') --Оконная функция разделяет по полу и берёт чемпиона из предыдущей строки SELECT athlete as champion, gender, year, LAG(athlete) OVER (PARTITION BY gender ORDER BY year ASC) AS last_champion FROM tennis_gold ORDER BY gender ASC, year ASC; --Найдем всех олимпийских чемпионов по теннису (мужчин и женщин отдельно), начиная с 2004 года, --и для каждого из них выяснить, кто был cледующим чемпионом. --Табличное выражение ищет теннисных чемпионов и выбирает нужные столбцы WITH tennis_gold AS (SELECT athlete, gender, year, country FROM windows_functions.summer_medals WHERE year >= 2004 AND sport = 'Tennis' AND event = 'singles' AND medal = 'Gold') --Оконная функция разделяет по полу и берёт чемпиона из следующей строки SELECT athlete as champion, gender, year, LEAD(athlete) OVER (PARTITION BY gender ORDER BY year ASC) AS last_champion FROM tennis_gold ORDER BY gender ASC, year ASC; --Ранжирование стран по числу олимпиад, в которых они участвовали, разными оконными функциями: -- Табличное выражение выбирает страны и считает годы WITH countries AS (SELECT sm.country, COUNT(DISTINCT sm.year) AS participated FROM windows_functions.summer_medals AS sm WHERE sm.country IN ('GBR', 'DEN', 'FRA', 'ITA','AUT') GROUP BY sm.country) -- Разные оконные функции ранжируют страны SELECT c.country, c.participated, ROW_NUMBER() OVER(ORDER BY c.participated DESC) AS "row_number", RANK() OVER(ORDER BY c.participated DESC) AS rank_number, DENSE_RANK() OVER(ORDER BY c.participated DESC) AS "dense_rank" FROM countries AS c ORDER BY c.participated DESC;