Загрузка данных


-- Задача 1

SELECT
    genre,
    COUNT(*) AS books_count,
    STRING_AGG(title, ', ' ORDER BY title) AS books_list
FROM books
GROUP BY genre
ORDER BY books_count DESC, genre;


-- Задача 2

SELECT
    l.loan_id,
    r.full_name,
    b.title,
    l.loan_date,
    (l.loan_date + INTERVAL '14 days')::date AS return_deadline,
    (l.loan_date - INTERVAL '3 days')::date AS three_days_before,
    CURRENT_DATE - l.loan_date AS days_since_loan,
    (l.loan_date + INTERVAL '14 days')::date
        - CURRENT_DATE AS days_until_deadline,
    TO_CHAR(l.loan_date, 'TMMonth YYYY') AS month_year
FROM loans AS l
JOIN readers AS r ON r.reader_id = l.reader_id
JOIN copies AS c ON c.copy_id = l.copy_id
JOIN books AS b ON b.book_id = c.book_id
ORDER BY l.loan_date, l.loan_id;


-- Задача 3

SELECT
    reader_id,
    full_name,
    SPLIT_PART(full_name, ' ', 2)
        || ' '
        || LEFT(SPLIT_PART(full_name, ' ', 1), 1)
        || '.' AS short_name,
    UPPER(email) AS email_upper,
    CASE
        WHEN POSITION('@' IN email) > 0
        THEN SUBSTRING(email FROM POSITION('@' IN email) + 1)
        ELSE NULL
    END AS email_domain
FROM readers
ORDER BY reader_id;


-- Задача 4

SELECT
    r.reader_id,
    r.full_name,
    COALESCE(r.phone, 'Не указан') AS phone,
    COALESCE(r.email, 'Не указан') AS email,
    COUNT(l.loan_id) AS loans_count,
    CASE
        WHEN COUNT(l.loan_id) = 0 THEN 'Низкая'
        WHEN COUNT(l.loan_id) BETWEEN 1 AND 2 THEN 'Средняя'
        ELSE 'Высокая'
    END AS activity
FROM readers AS r
LEFT JOIN loans AS l ON l.reader_id = r.reader_id
GROUP BY
    r.reader_id,
    r.full_name,
    r.phone,
    r.email
ORDER BY loans_count DESC, r.reader_id;


-- Задача 5

WITH book_statistics AS (
    SELECT
        b.book_id,
        b.title,
        b.genre,
        COUNT(l.loan_id) AS loans_count
    FROM books AS b
    LEFT JOIN copies AS c ON c.book_id = b.book_id
    LEFT JOIN loans AS l ON l.copy_id = c.copy_id
    GROUP BY b.book_id, b.title, b.genre
)
SELECT
    book_id,
    title,
    genre,
    loans_count,
    ROW_NUMBER() OVER (
        ORDER BY loans_count DESC, book_id
    ) AS overall_place,
    ROW_NUMBER() OVER (
        PARTITION BY genre
        ORDER BY loans_count DESC, book_id
    ) AS genre_place
FROM book_statistics
ORDER BY overall_place;