Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Empty file added Week3/solutions/eighth_task.sql
Empty file.
21 changes: 21 additions & 0 deletions Week3/solutions/fifth_task.sql
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@

Comment thread
ASketin marked this conversation as resolved.
-- Для каждого сотрудника подсчитать количество клиентов, количестов выполненных заказов,
-- количество уникальных адресов доставки и общее число приобретенных треков и вывести полное имя сотрудника.
-- (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,
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.employee_id;
9 changes: 9 additions & 0 deletions Week3/solutions/first_task.sql
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@

Comment thread
ASketin marked this conversation as resolved.
-- Вывести все альбомы со средней длинной трека, большей 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.album_id
HAVING AVG(t.milliseconds) > 250000;
12 changes: 12 additions & 0 deletions Week3/solutions/fourth_task.sql
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@

Comment thread
ASketin marked this conversation as resolved.
-- Для всех треков жанра 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.artist_id;
31 changes: 31 additions & 0 deletions Week3/solutions/ninth_task.sql
Original file line number Diff line number Diff line change
@@ -0,0 +1,31 @@


-- Для каждого альбома жанр определяется как наибольшая суммарная продолжительность треков по жанру.
-- Вывести альбом, жанр, и общее количество купленных песен по нему. (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
)

SELECT title as album_name,
g.name as genre_name,
cnt
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)
Copy link
Copy Markdown
Owner

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Не схлопнутся ли тут альбомы?

JOIN genre g USING (genre_id);
11 changes: 11 additions & 0 deletions Week3/solutions/second_task.sql
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@

Comment thread
ASketin marked this conversation as resolved.
-- Для каждого набора жанр, тип медиа вывести количество треков.
-- Если для набора жанр, тип медиа треков нет, то такой набор выводить не требуется.
-- (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;
52 changes: 52 additions & 0 deletions Week3/solutions/seventh_task.sql
Original file line number Diff line number Diff line change
@@ -0,0 +1,52 @@

Comment thread
ASketin marked this conversation as resolved.
-- Вывести компании, которые приобрели больше всех композиций по каждому из жанров.
-- При этом указать самую популярную композицию по жанру у данной компании.
-- (популярность определяется по количеству покупок) (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,
SUM(quantity) as count
FROM company_stat
GROUP BY company, genre_id
),
count_track AS (
SELECT company,
genre_id,
name,
SUM(quantity) 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;
23 changes: 23 additions & 0 deletions Week3/solutions/sixth_task.sql
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@

Comment thread
ASketin marked this conversation as resolved.
-- Выполнить сегментацию клиентов по количеству букв а в его фамилии - Группа '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 LIKE '%Metal'
GROUP BY segment_group;
52 changes: 52 additions & 0 deletions Week3/solutions/tenth_task.sql
Original file line number Diff line number Diff line change
@@ -0,0 +1,52 @@

Comment thread
ASketin marked this conversation as resolved.

-- Для каждого альбома тип медиа определяется как наибольшая суммарный размер треков по жанру.
-- Для каждого исполнителя вывести тип медиа, соответствующий наибольшему количеству типо медиа по альбомам,
-- где они участвуют.
-- Вывести имя исполнителя, тип медиа, количество альбомов с данными типом, общее количество альбомов.
-- (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
)

SELECT art.name as artist_name,
met.name as media_type_name,
sum as media_cnt,
total as whole_cnt
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;
15 changes: 15 additions & 0 deletions Week3/solutions/third_task.sql
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@

Comment thread
ASketin marked this conversation as resolved.
-- Вывести сотрудников, которые старше своего менеджера, но были наняты позже своего менеджера.
-- Вывести полное имя сотрудника(Фамилия<Пробел>Имя), день рождения, дата найма,
-- полное имя менеджера, день рождения, дата найма.
-- (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;
83 changes: 83 additions & 0 deletions Week4/solutions/fifth_task.sql
Original file line number Diff line number Diff line change
@@ -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
20 changes: 20 additions & 0 deletions Week4/solutions/first_task.sql
Original file line number Diff line number Diff line change
@@ -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
Loading