From 2ec47b165be5c986a66ea86e2dbbec7658d4902d Mon Sep 17 00:00:00 2001 From: Master-Pc Date: Sat, 27 Mar 2021 16:49:59 +0300 Subject: [PATCH 1/4] Initial commit --- Week3/solutions/eighth_task.sql | 0 Week3/solutions/fifth_task.sql | 21 +++++++++++++ Week3/solutions/first_task.sql | 9 ++++++ Week3/solutions/fourth_task.sql | 12 ++++++++ Week3/solutions/ninth_task.sql | 28 +++++++++++++++++ Week3/solutions/second_task.sql | 11 +++++++ Week3/solutions/seventh_task.sql | 52 ++++++++++++++++++++++++++++++++ Week3/solutions/sixth_task.sql | 23 ++++++++++++++ Week3/solutions/tenth_task.sql | 43 ++++++++++++++++++++++++++ Week3/solutions/third_task.sql | 15 +++++++++ 10 files changed, 214 insertions(+) create mode 100644 Week3/solutions/eighth_task.sql create mode 100644 Week3/solutions/fifth_task.sql create mode 100644 Week3/solutions/first_task.sql create mode 100644 Week3/solutions/fourth_task.sql create mode 100644 Week3/solutions/ninth_task.sql create mode 100644 Week3/solutions/second_task.sql create mode 100644 Week3/solutions/seventh_task.sql create mode 100644 Week3/solutions/sixth_task.sql create mode 100644 Week3/solutions/tenth_task.sql create mode 100644 Week3/solutions/third_task.sql diff --git a/Week3/solutions/eighth_task.sql b/Week3/solutions/eighth_task.sql new file mode 100644 index 0000000..e69de29 diff --git a/Week3/solutions/fifth_task.sql b/Week3/solutions/fifth_task.sql new file mode 100644 index 0000000..c953e1b --- /dev/null +++ b/Week3/solutions/fifth_task.sql @@ -0,0 +1,21 @@ + +-- Для каждого сотрудника подсчитать количество клиентов, количестов выполненных заказов, +-- количество уникальных адресов доставки и общее число приобретенных треков и вывести полное имя сотрудника. +-- (employee_full_name, invoices_count, customers_count, addresses_count, tracks_count) + +SELECT e.first_name || ' ' || e.last_name as employee_full_name, + SUM(cnt_inv) as invoices_count, + COUNT(c.customer_id) as customers_count, + SUM(cnt_addr) as addresses_count, + SUM(cnt_trc) as tracks_count +FROM customer c JOIN ( + SELECT customer_id, + count(distinct invoice_id) as cnt_inv, + count(distinct billing_address) as cnt_addr, + count(track_id) as cnt_trc + FROM customer c + JOIN invoice i USING (customer_id) + JOIN invoice_line il USING (invoice_id) + GROUP BY customer_id) st USING (customer_id) + JOIN employee e on c.support_rep_id = e.employee_id +GROUP BY e.first_name || ' ' || e.last_name; \ No newline at end of file diff --git a/Week3/solutions/first_task.sql b/Week3/solutions/first_task.sql new file mode 100644 index 0000000..bc1210c --- /dev/null +++ b/Week3/solutions/first_task.sql @@ -0,0 +1,9 @@ + +-- Вывести все альбомы со средней длинной трека, большей 250 секунд. +-- Вывести название альбома и количество треков. (album_name, cnt). + +SELECT a.title as album_name, + COUNT(track_id) as cnt +FROM album a JOIN track t USING (album_id) +GROUP BY a.title +HAVING AVG(t.milliseconds) > 250000; \ No newline at end of file diff --git a/Week3/solutions/fourth_task.sql b/Week3/solutions/fourth_task.sql new file mode 100644 index 0000000..4ec0b63 --- /dev/null +++ b/Week3/solutions/fourth_task.sql @@ -0,0 +1,12 @@ + +-- Для всех треков жанра Rock и Metal, для каждого артиста подсчитать количество треков. +-- Вывести имя артиста, количество треков. (artist_name, qty) + +SELECT art.name as artist_name, + COUNT(track_id) as qty +FROM artist art JOIN album a USING (artist_id) + JOIN track t USING (album_id) + JOIN (SELECT * + FROM genre + WHERE name IN ('Rock', 'Metal')) g USING (genre_id) +GROUP BY art.name; \ No newline at end of file diff --git a/Week3/solutions/ninth_task.sql b/Week3/solutions/ninth_task.sql new file mode 100644 index 0000000..74e7963 --- /dev/null +++ b/Week3/solutions/ninth_task.sql @@ -0,0 +1,28 @@ + + +-- Для каждого альбома жанр определяется как наибольшая суммарная продолжительность треков по жанру. +-- Вывести альбом, жанр, и общее количество купленных песен по нему. (album_name, genre_name, cnt) + +WITH genre_stat AS ( + SELECT genre_id, + SUM(milliseconds) sum + FROM track t + GROUP BY genre_id +), + genre_max AS ( + SELECT genre_id, + MAX(sum) as genre_name + FROM genre_stat + GROUP BY genre_id + ) + +SELECT DISTINCT title, + genre_name, + cnt +FROM album a JOIN track t on a.album_id = t.album_id + JOIN genre_max USING (genre_id) + JOIN (SELECT title, + sum(quantity) as cnt + FROM album a JOIN track t on a.album_id = t.album_id + JOIN invoice_line il on t.track_id = il.track_id + GROUP BY title) res USING (title); \ No newline at end of file diff --git a/Week3/solutions/second_task.sql b/Week3/solutions/second_task.sql new file mode 100644 index 0000000..1619dc0 --- /dev/null +++ b/Week3/solutions/second_task.sql @@ -0,0 +1,11 @@ + +-- Для каждого набора жанр, тип медиа вывести количество треков. +-- Если для набора жанр, тип медиа треков нет, то такой набор выводить не требуется. +-- (genre_name, media_type_name, cnt) + +SELECT genre.name as genre_name, + media_type.name as media_type_name, + COUNT(track_id) as cnt +FROM track JOIN media_type USING (media_type_id) + JOIN genre USING (genre_id) +GROUP BY genre.name, media_type.name; \ No newline at end of file diff --git a/Week3/solutions/seventh_task.sql b/Week3/solutions/seventh_task.sql new file mode 100644 index 0000000..33129ef --- /dev/null +++ b/Week3/solutions/seventh_task.sql @@ -0,0 +1,52 @@ + +-- Вывести компании, которые приобрели больше всех композиций по каждому из жанров. +-- При этом указать самую популярную композицию по жанру у данной компании. +-- (популярность определяется по количеству покупок) (company_name, track_name) + + +WITH company_stat AS ( + SELECT * + FROM invoice i + JOIN invoice_line il USING (invoice_id) + JOIN track t USING (track_id) + JOIN (SELECT customer_id, + company + FROM customer + WHERE company IS NOT NULL) comp USING (customer_id) +), + top_chart AS( + SELECT company, + genre_id, + COUNT(track_id) as count + FROM company_stat + GROUP BY company, genre_id + ), + count_track AS ( + SELECT company, + genre_id, + name, + COUNT(*) as pop + FROM company_stat + GROUP BY company,genre_id,name + ), + top_track AS ( + SELECT company, + genre_id, + name, + MAX(pop) + FROM count_track + GROUP BY company,genre_id,name + ) + +SELECT DISTINCT ON (2) + top_chart.company, + tp.genre_id, + name +FROM top_chart +JOIN (SELECT genre_id, + MAX(count) as max + FROM top_chart + GROUP BY genre_id ) g_top ON top_chart.genre_id = g_top.genre_id + AND top_chart.count = g_top.max +JOIN top_track tp ON top_chart.company = tp.company + AND top_chart.genre_id = tp.genre_id; \ No newline at end of file diff --git a/Week3/solutions/sixth_task.sql b/Week3/solutions/sixth_task.sql new file mode 100644 index 0000000..4896fd6 --- /dev/null +++ b/Week3/solutions/sixth_task.sql @@ -0,0 +1,23 @@ + +-- Выполнить сегментацию клиентов по количеству букв а в его фамилии - Группа 'A' - 0 букв, 'B' - 1 буква, +-- 'C' - 2 буквы, 'D' - 3 и более букв. Для каждой группы вывести количество уникальных типов медиа, +-- купленных клиентами по трекам из различных жанров метала. +-- Вывести имя группы и количество уникальных типов медиа +-- (segment_group, cnt) + +select segment_group, + COUNT(distinct media_type_id) +FROM invoice i JOIN invoice_line il on i.invoice_id = il.invoice_id + JOIN track ON il.track_id = track.track_id + JOIN genre g on track.genre_id = g.genre_id + JOIN (SELECT customer_id, + last_name, + CASE + WHEN CHAR_LENGTH(last_name) - CHAR_LENGTH(REPLACE(last_name, 'a', '')) = 0 THEN 'A' + WHEN CHAR_LENGTH(last_name) - CHAR_LENGTH(REPLACE(last_name, 'a', '')) = 1 THEN 'B' + WHEN CHAR_LENGTH(last_name) - CHAR_LENGTH(REPLACE(last_name, 'a', '')) = 2 THEN 'C' + WHEN CHAR_LENGTH(last_name) - CHAR_LENGTH(REPLACE(last_name, 'a', '')) > 2 THEN 'D' + END as segment_group + FROM customer) seg ON i.customer_id = seg.customer_id +WHERE g.name IN ('Metal', 'Heavy Metal') +GROUP BY segment_group; \ No newline at end of file diff --git a/Week3/solutions/tenth_task.sql b/Week3/solutions/tenth_task.sql new file mode 100644 index 0000000..52b0f65 --- /dev/null +++ b/Week3/solutions/tenth_task.sql @@ -0,0 +1,43 @@ + + +-- Для каждого альбома тип медиа определяется как наибольшая суммарный размер треков по жанру. +-- Для каждого исполнителя вывести тип медиа, соответствующий наибольшему количеству типо медиа по альбомам, +-- где они участвуют. +-- Вывести имя исполнителя, тип медиа, количество альбомов с данными типом, общее количество альбомов. +-- (artist_name, media_type_name, media_cnt, whole_cnt) + + +WITH genre_stat AS ( + SELECT genre_id, + SUM(bytes) sum + FROM track t + GROUP BY genre_id +), + genre_max AS ( + SELECT genre_id, + MAX(sum) as media_type + FROM genre_stat + GROUP BY genre_id + ), + general_stat AS ( + SELECT art.name as name, + media_type, + t2.album_id as album_id + FROM artist art JOIN album a on art.artist_id = a.artist_id + JOIN track t2 on a.album_id = t2.album_id + JOIN genre_max USING (genre_id) + ) + + +SELECT f.name as artist_name, + f.media_type as media_type_name, + f.cnt as media_cnt, + total as whole_cnt +FROM (SELECT name, + media_type, + COUNT(album_id) as cnt +FROM general_stat +GROUP BY name, media_type) f JOIN (SELECT name, + count(album_id) as total +FROM general_stat +GROUP BY name) s on f.name = s.name \ No newline at end of file diff --git a/Week3/solutions/third_task.sql b/Week3/solutions/third_task.sql new file mode 100644 index 0000000..884e3f1 --- /dev/null +++ b/Week3/solutions/third_task.sql @@ -0,0 +1,15 @@ + +-- Вывести сотрудников, которые старше своего менеджера, но были наняты позже своего менеджера. +-- Вывести полное имя сотрудника(Фамилия<Пробел>Имя), день рождения, дата найма, +-- полное имя менеджера, день рождения, дата найма. +-- (employee_full_name, employee_birth_date, employee_hire_date, +-- manager_full_name, manager_birth_date, manager_hire_date) + +SELECT e.first_name || ' ' || e.last_name as employee_full_name, + e.birth_date as employee_birth_date, + e.hire_date as employee_hire_date, + m.first_name || ' ' || m.last_name as manager_full_name, + m.birth_date as manager_birth_date, + m.hire_date as manager_hire_date +FROM employee e JOIN employee m ON m.employee_id = e.reports_to +WHERE e.birth_date < m.birth_date AND e.hire_date > m.hire_date; \ No newline at end of file From 2c3225f685aa3d67fc220ca5c939b25e0c909645 Mon Sep 17 00:00:00 2001 From: Master-Pc Date: Mon, 29 Mar 2021 22:15:32 +0300 Subject: [PATCH 2/4] Another try to pass review --- Week3/solutions/fifth_task.sql | 4 +- Week3/solutions/first_task.sql | 2 +- Week3/solutions/fourth_task.sql | 2 +- Week3/solutions/ninth_task.sql | 47 ++++++++++---------- Week3/solutions/seventh_task.sql | 6 +-- Week3/solutions/sixth_task.sql | 2 +- Week3/solutions/tenth_task.sql | 75 ++++++++++++++++++-------------- 7 files changed, 75 insertions(+), 63 deletions(-) diff --git a/Week3/solutions/fifth_task.sql b/Week3/solutions/fifth_task.sql index c953e1b..779c7df 100644 --- a/Week3/solutions/fifth_task.sql +++ b/Week3/solutions/fifth_task.sql @@ -12,10 +12,10 @@ FROM customer c JOIN ( SELECT customer_id, count(distinct invoice_id) as cnt_inv, count(distinct billing_address) as cnt_addr, - count(track_id) as cnt_trc + sum(quantity) as cnt_trc FROM customer c JOIN invoice i USING (customer_id) JOIN invoice_line il USING (invoice_id) GROUP BY customer_id) st USING (customer_id) JOIN employee e on c.support_rep_id = e.employee_id -GROUP BY e.first_name || ' ' || e.last_name; \ No newline at end of file +GROUP BY e.employee_id; \ No newline at end of file diff --git a/Week3/solutions/first_task.sql b/Week3/solutions/first_task.sql index bc1210c..a258110 100644 --- a/Week3/solutions/first_task.sql +++ b/Week3/solutions/first_task.sql @@ -5,5 +5,5 @@ SELECT a.title as album_name, COUNT(track_id) as cnt FROM album a JOIN track t USING (album_id) -GROUP BY a.title +GROUP BY a.album_id HAVING AVG(t.milliseconds) > 250000; \ No newline at end of file diff --git a/Week3/solutions/fourth_task.sql b/Week3/solutions/fourth_task.sql index 4ec0b63..9e89a6b 100644 --- a/Week3/solutions/fourth_task.sql +++ b/Week3/solutions/fourth_task.sql @@ -9,4 +9,4 @@ FROM artist art JOIN album a USING (artist_id) JOIN (SELECT * FROM genre WHERE name IN ('Rock', 'Metal')) g USING (genre_id) -GROUP BY art.name; \ No newline at end of file +GROUP BY art.artist_id; \ No newline at end of file diff --git a/Week3/solutions/ninth_task.sql b/Week3/solutions/ninth_task.sql index 74e7963..ed12b06 100644 --- a/Week3/solutions/ninth_task.sql +++ b/Week3/solutions/ninth_task.sql @@ -2,27 +2,30 @@ -- Для каждого альбома жанр определяется как наибольшая суммарная продолжительность треков по жанру. -- Вывести альбом, жанр, и общее количество купленных песен по нему. (album_name, genre_name, cnt) +WITH stat AS ( + SELECT title, + album_id, + genre_id, + SUM(milliseconds) as duration + FROM album al + JOIN artist a USING (artist_id) + JOIN track t USING (album_id) + GROUP BY album_id, genre_id +), genre_stat AS ( + SELECT album_id, + MAX(duration) as sum + FROM stat + GROUP BY album_id +) -WITH genre_stat AS ( - SELECT genre_id, - SUM(milliseconds) sum - FROM track t - GROUP BY genre_id -), - genre_max AS ( - SELECT genre_id, - MAX(sum) as genre_name - FROM genre_stat - GROUP BY genre_id - ) - -SELECT DISTINCT title, - genre_name, +SELECT title as album_name, + g.name as genre_name, cnt -FROM album a JOIN track t on a.album_id = t.album_id - JOIN genre_max USING (genre_id) - JOIN (SELECT title, - sum(quantity) as cnt - FROM album a JOIN track t on a.album_id = t.album_id - JOIN invoice_line il on t.track_id = il.track_id - GROUP BY title) res USING (title); \ No newline at end of file +FROM genre_stat gst JOIN stat st ON gst.album_id = st.album_id + AND gst.sum = st.duration +JOIN (SELECT title, + SUM(quantity) as cnt + FROM album a JOIN track t on a.album_id = t.album_id + JOIN invoice_line il on t.track_id = il.track_id + GROUP BY title) res USING (title) +JOIN genre g USING (genre_id); \ No newline at end of file diff --git a/Week3/solutions/seventh_task.sql b/Week3/solutions/seventh_task.sql index 33129ef..3c4a985 100644 --- a/Week3/solutions/seventh_task.sql +++ b/Week3/solutions/seventh_task.sql @@ -17,7 +17,7 @@ WITH company_stat AS ( top_chart AS( SELECT company, genre_id, - COUNT(track_id) as count + SUM(quantity) as count FROM company_stat GROUP BY company, genre_id ), @@ -25,7 +25,7 @@ WITH company_stat AS ( SELECT company, genre_id, name, - COUNT(*) as pop + SUM(quantity) as pop FROM company_stat GROUP BY company,genre_id,name ), @@ -38,7 +38,7 @@ WITH company_stat AS ( GROUP BY company,genre_id,name ) -SELECT DISTINCT ON (2) +SELECT DISTINCT ON(2) top_chart.company, tp.genre_id, name diff --git a/Week3/solutions/sixth_task.sql b/Week3/solutions/sixth_task.sql index 4896fd6..6d571c0 100644 --- a/Week3/solutions/sixth_task.sql +++ b/Week3/solutions/sixth_task.sql @@ -19,5 +19,5 @@ FROM invoice i JOIN invoice_line il on i.invoice_id = il.invoice_id WHEN CHAR_LENGTH(last_name) - CHAR_LENGTH(REPLACE(last_name, 'a', '')) > 2 THEN 'D' END as segment_group FROM customer) seg ON i.customer_id = seg.customer_id -WHERE g.name IN ('Metal', 'Heavy Metal') +WHERE g.name LIKE '%Metal' GROUP BY segment_group; \ No newline at end of file diff --git a/Week3/solutions/tenth_task.sql b/Week3/solutions/tenth_task.sql index 52b0f65..490a356 100644 --- a/Week3/solutions/tenth_task.sql +++ b/Week3/solutions/tenth_task.sql @@ -6,38 +6,47 @@ -- Вывести имя исполнителя, тип медиа, количество альбомов с данными типом, общее количество альбомов. -- (artist_name, media_type_name, media_cnt, whole_cnt) +WITH stat AS ( + SELECT album_id, + media_type_id, + SUM(bytes) as size + FROM album al + JOIN artist a USING (artist_id) + JOIN track t USING (album_id) + GROUP BY album_id, media_type_id +), media_stat AS ( + SELECT album_id, + MAX(size) as sum + FROM stat + GROUP BY album_id +), album_type AS ( + SELECT st.album_id as album_id, + st.media_type_id as mt + FROM media_stat mst JOIN stat st ON mst.album_id = st.album_id + AND mst.sum = st.size +), artist_stat AS ( + SELECT artist_id, + mt, + count(album_id) as count + FROM album_type + JOIN album al USING (album_id) + GROUP BY artist_id, mt +), artist_max AS ( + SELECT artist_id, + MAX(count) as sum + FROM artist_stat + GROUP BY artist_id +) -WITH genre_stat AS ( - SELECT genre_id, - SUM(bytes) sum - FROM track t - GROUP BY genre_id -), - genre_max AS ( - SELECT genre_id, - MAX(sum) as media_type - FROM genre_stat - GROUP BY genre_id - ), - general_stat AS ( - SELECT art.name as name, - media_type, - t2.album_id as album_id - FROM artist art JOIN album a on art.artist_id = a.artist_id - JOIN track t2 on a.album_id = t2.album_id - JOIN genre_max USING (genre_id) - ) - - -SELECT f.name as artist_name, - f.media_type as media_type_name, - f.cnt as media_cnt, +SELECT art.name as artist_name, + met.name as media_type_name, + sum as media_cnt, total as whole_cnt -FROM (SELECT name, - media_type, - COUNT(album_id) as cnt -FROM general_stat -GROUP BY name, media_type) f JOIN (SELECT name, - count(album_id) as total -FROM general_stat -GROUP BY name) s on f.name = s.name \ No newline at end of file +FROM artist_max am JOIN artist_stat ast ON am.artist_id = ast.artist_id + AND am.sum = ast.count +JOIN (SELECT artist_id, + sum(count) as total + FROM artist_stat + GROUP BY artist_id) t ON am.artist_id = t.artist_id +JOIN media_type met ON met.media_type_id = mt + JOIN artist art ON art.artist_id = am.artist_id; \ No newline at end of file From 73e86c5f0194149a92bc9888595436655a3330d2 Mon Sep 17 00:00:00 2001 From: Master-Pc Date: Sun, 4 Apr 2021 20:44:14 +0300 Subject: [PATCH 3/4] 4/7 task --- Week4/solutions/first_task.sql | 20 +++++++++++ Week4/solutions/fourth_task.sql | 60 +++++++++++++++++++++++++++++++++ Week4/solutions/second_task.sql | 27 +++++++++++++++ Week4/solutions/third_task.sql | 25 ++++++++++++++ 4 files changed, 132 insertions(+) create mode 100644 Week4/solutions/first_task.sql create mode 100644 Week4/solutions/fourth_task.sql create mode 100644 Week4/solutions/second_task.sql create mode 100644 Week4/solutions/third_task.sql diff --git a/Week4/solutions/first_task.sql b/Week4/solutions/first_task.sql new file mode 100644 index 0000000..bb558e5 --- /dev/null +++ b/Week4/solutions/first_task.sql @@ -0,0 +1,20 @@ +-- Для каждого артиста вывести все жанры, которые есть в его песнях, и для каждого жанра вывести +-- наиболее продолжительную песню. (artist_name, genre_name, track_name, track_length) + +WITH stat AS ( + SELECT art.name as artist_name, + g.name as genre_name, + t.name as track_name, + milliseconds as track_length, + row_number() over (partition by art.artist_id, genre_id order by milliseconds DESC) as rn + FROM artist art JOIN album a USING (artist_id) + JOIN track t USING (album_id) + JOIN genre g USING (genre_id) +) + +SELECT artist_name, + genre_name, + track_name, + track_length +FROM stat +WHERE rn = 1 \ No newline at end of file diff --git a/Week4/solutions/fourth_task.sql b/Week4/solutions/fourth_task.sql new file mode 100644 index 0000000..37863a4 --- /dev/null +++ b/Week4/solutions/fourth_task.sql @@ -0,0 +1,60 @@ + + +-- Для каждого плейлиста вывести трек с наибольшей продолжительностью, +-- трек с наименьшей стоимостью (если у треков одинаковая стоимость, то вывести тот, который весит меньше всех), +-- и жанр данного плейлиста (жанром плейлиста называется тот жанр, треков которого больше всех в плейлисте) +-- (playlist_name, longest_track_name, minimal_price_track, playlist_genre_name). +WITH source_data AS ( + SELECT pl.playlist_id as playlist_id, + pl.name as playlist_name, + t.name as track_name, + milliseconds, + unit_price, + bytes, + track_id, + genre_id + FROM playlist pl JOIN playlist_track pt USING (playlist_id) + JOIN track t USING (track_id) +), + pl_long AS ( + SELECT playlist_id, + playlist_name, + track_name as longest_track_name, + row_number() over (partition by playlist_id order by milliseconds DESC ) as rn + FROM source_data +), + pl_min AS ( + SELECT playlist_id, + track_name as minimal_price, + row_number() over (partition by playlist_id order by unit_price DESC, bytes) as rn + FROM source_data +), + pl_genre_cnt AS ( + SELECT DISTINCT ON (1, 2) playlist_id, + g.name, + count(track_id) over (partition by playlist_id, g.genre_id) as cnt + FROM source_data sd + JOIN genre g on sd.genre_id = g.genre_id +), + pl_genre AS ( + SELECT playlist_id, + name, + row_number() over (partition by playlist_id order by cnt DESC ) as rn + FROM pl_genre_cnt + ) + +SELECT playlist_id, + playlist_name, + longest_track_name, + minimal_price, + name +FROM (SELECT * + FROM pl_min + WHERE rn = 1 + ) f + JOIN (SELECT * + FROM pl_long + WHERE rn = 1) s USING (playlist_id) +JOIN (SELECT * + FROM pl_genre + WHERE rn = 1) pl USING (playlist_id); \ No newline at end of file diff --git a/Week4/solutions/second_task.sql b/Week4/solutions/second_task.sql new file mode 100644 index 0000000..d10c9d1 --- /dev/null +++ b/Week4/solutions/second_task.sql @@ -0,0 +1,27 @@ + + +-- Для каждой компании вывести трек, за который компания заплатила наибольшую сумму, +-- вывести жанр данного трека и его альбом. (company_name, genre_name, track_name) + +WITH stat AS ( + SELECT company as company_name, + g.name as genre_name, + t.name as track_name, + a.title as album_name, + row_number() OVER (PARTITION BY company ORDER BY quantity * t.unit_price DESC) as rn + FROM invoice inv + JOIN (SELECT company, + customer_id + FROM customer + WHERE company IS NOT NULL) c USING (customer_id) + JOIN invoice_line il USING (invoice_id) + JOIN track t USING (track_id) + JOIN genre g USING (genre_id) + JOIN album a USING (album_id) +) + +SELECT company_name, + genre_name, + track_name +FROM stat +WHERE rn = 1; \ No newline at end of file diff --git a/Week4/solutions/third_task.sql b/Week4/solutions/third_task.sql new file mode 100644 index 0000000..de3386f --- /dev/null +++ b/Week4/solutions/third_task.sql @@ -0,0 +1,25 @@ + + +-- Вывести все интервалы, в которые не было нанято ни одного сотрудника. +-- Минимальная дата - 1999-01-01, Максимальная - 2020-01-01. +-- Например, если первый сотрудник был нанят 2010-01-02, то первая строка в ответе +-- будет (1999-01-01, 2010-01-01). +-- Интервалы должны быть непересекающимися и закрытыми. +-- Строки должны быть выведене в результирующей выборке в порядке возрастания +-- (date_start, date_end) + +INSERT INTO employee(employee_id, first_name, last_name, hire_date) + VALUES (0, 'blank', 'blank', to_timestamp('1999-01-01', 'YYYY-MM-DD')), + ((SELECT COUNT(*) + 1 FROM employee), 'blank', 'blank', to_timestamp('2020-01-02', 'YYYY-MM-DD')); + +WITH tmp as ( + SELECT DATE(first_value(hire_date) OVER (ORDER BY hire_date + ROWS BETWEEN current row and 1 following)) as first, + DATE(last_value(hire_date) OVER (ORDER BY hire_date + ROWS BETWEEN current row and 1 following)) as second + FROM employee +) + +SELECT (first, second) +FROM tmp +WHERE first != second; \ No newline at end of file From 9882856971f11222031f157b00b20c644949529a Mon Sep 17 00:00:00 2001 From: Master-Pc Date: Sun, 11 Apr 2021 20:33:56 +0300 Subject: [PATCH 4/4] fifth task was added --- Week4/solutions/fifth_task.sql | 83 ++++++++++++++++++++++++++++++++++ 1 file changed, 83 insertions(+) create mode 100644 Week4/solutions/fifth_task.sql diff --git a/Week4/solutions/fifth_task.sql b/Week4/solutions/fifth_task.sql new file mode 100644 index 0000000..71d3f66 --- /dev/null +++ b/Week4/solutions/fifth_task.sql @@ -0,0 +1,83 @@ + +-- Задание 5 +-- Для каждого сотрудника вывести общее количество купленных треков, проведенных им в заказе, +-- самый часто используемый жанр треков, и общее число треков по минимальной стоимости. +-- Если у сотрудника есть подчиненные, то все величины должны быть подсчитаны с учетом подчинения +-- (то есть все заказы, которые обслужил сам сотрудник + заказы его подчиненных). +-- Учесть потенциальную глубину вложенности. +-- (employee_name, tracks_count, most_popular_genre, tracks_minimal_price). +WITH source_date AS ( + SELECT employee_id, + genre_id, + t.track_id as track_id, + t.unit_price + FROM employee e JOIN customer c + ON e.employee_id = c.support_rep_id + JOIN invoice i on c.customer_id = i.customer_id + JOIN invoice_line il on i.invoice_id = il.invoice_id + JOIN track t on il.track_id = t.track_id +), price_amnt AS ( + SELECT employee_id, + unit_price, + COUNT(track_id) as count + FROM source_date + GROUP BY employee_id, unit_price +), rank_price AS ( + SELECT employee_id, + unit_price, + count as count_price, + row_number() over (PARTITION BY employee_id ORDER BY unit_price, count DESC) as rn + FROM price_amnt +), genre_amnt AS ( + SELECT employee_id, + genre_id, + COUNT(track_id) as count_genre + FROM source_date + GROUP BY employee_id, genre_id +), rank_genre AS ( + SELECT + employee_id, + genre_id, + count_genre, + row_number() over (PARTITION BY employee_id ORDER BY count_genre DESC) as rn + FROM genre_amnt +), worker_stat AS (SELECT DISTINCT ON(1, 2) employee_id as eid, + COUNT(track_id) OVER (PARTITION BY employee_id) as tracks_count, + rg.genre_id as most_popular_genre, + count_price as tracks_minimal_price + FROM source_date sd + JOIN (SELECT * FROM rank_price WHERE rn = 1) rp USING (employee_id) + JOIN (SELECT * FROM rank_genre WHERE rn = 1) rg USING (employee_id) +), manager_stat AS ( + SELECT reports_to as eid, + SUM(tracks_count) as tracks_count, + mode() within group (order by most_popular_genre) most_popular_genre, + SUM(tracks_minimal_price) as tracks_minimal_price + FROM worker_stat ws JOIN employee e1 ON ws.eid = e1.employee_id + GROUP BY reports_to +), directory_stat AS ( + SELECT e.reports_to as eid, + SUM(tracks_count) as tracks_count, + mode() within group (order by most_popular_genre) most_popular_genre, + SUM(tracks_minimal_price) as tracks_minimal_price + FROM manager_stat ms + JOIN employee e ON e.employee_id = ms.eid + GROUP BY employee_id +), general_report AS ( + SELECT * + FROM manager_stat + UNION + SELECT * + FROM directory_stat + UNION + SELECT * + FROM worker_stat +) + +SELECT first_name || ' ' || last_name as employee_name, + tracks_count, + g.name as most_popular_genre, + tracks_minimal_price +FROM general_report gr JOIN employee e + ON gr.eid = e.employee_id + JOIN genre g ON gr.most_popular_genre = g.genre_id \ No newline at end of file