Аналітичні звіти — це систематизовані уявлення даних, які допомагають приймати рішення. Наприклад:
- Менеджери хочуть бачити, якою була виручка за минулий місяць.
- Аналітики шукають тренди на ринку.
- Розробники моніторять продуктивність застосунку.
Уяви собі, що ти — шеф-кухар, який керує величезним рестораном. Щоб зрозуміти, які страви замовляють найчастіше, тобі потрібен звіт. PostgreSQL у цьому випадку — це твоя база даних рецептів і замовлень, а PL/pgSQL (процедури) — твій помічник на кухні, який автоматизує процес аналізу замовлень.
Основи побудови аналітичних звітів
Аналітичний звіт — це інструмент для агрегації, фільтрації, сортування та впорядкування даних з метою отримання корисної інформації. Зазвичай структура звіту включає такі етапи:
- Підготовка даних: вибірка інформації з таблиць, фільтрація та попередня обробка.
- Агрегація даних: розрахунок метрик (середній чек, загальна сума продажів тощо).
- Форматування: впорядкування даних у зручному для сприйняття вигляді.
- Вивід результатів: представлення звіту користувачам або запис у таблицю для зберігання.
Кожен із цих етапів можна реалізувати за допомогою процедур PL/pgSQL.
Створення процедури для аналітичного звіту
Давай розберемо базовий приклад створення аналітичного звіту. Припустимо, у нас є таблиця orders, у якій зберігаються дані про замовлення:
CREATE TABLE orders (
id SERIAL PRIMARY KEY,
customer_id INT,
order_date DATE,
total_amount NUMERIC(10, 2)
);
Наша задача: створити звіт про суму продажів за вказаний місяць. Тобто, ми хочемо бачити:
- Місяць.
- Загальну суму продажів за цей місяць.
Структура процедури
Ось план нашої процедурки (не лякайся, програмування на PL/pgSQL не кусається):
- Приймаємо вхідний параметр — місяць.
- Вибираємо дані за цей місяць із таблиці
orders. - Рахуємо загальну суму продажів.
- Повертаємо результат.
Реалізація процедури
Приклад коду:
CREATE OR REPLACE FUNCTION monthly_sales_report(p_month DATE)
RETURNS TABLE (
month DATE,
total_sales NUMERIC(10, 2)
) AS $$
BEGIN
-- Вибираємо дані за вказаний місяць і агрегуємо їх
RETURN QUERY
SELECT
DATE_TRUNC('month', o.order_date) AS month,
SUM(o.total_amount) AS total_sales
FROM orders o
WHERE DATE_TRUNC('month', o.order_date) = DATE_TRUNC('month', p_month)
GROUP BY 1;
END;
$$ LANGUAGE plpgsql;
- Вхідний параметр:
p_month— дата. Ми будемо використовувати його, щоб фільтрувати дані по місяцю. - RETURN QUERY: це магічна штука, яка дозволяє повернути дані прямо з процедури.
- DATE_TRUNC: використовується для округлення
order_dateдо початку місяця. - SUM: агрегатна функція для підрахунку суми всіх замовлень.
- GROUP BY: групуємо дані по місяцю, бо звіти будуються по місяцях.
Тепер ми можемо викликати нашу функцію:
SELECT * FROM monthly_sales_report('2023-08-01');
І отримаємо щось типу:
| month | total_sales |
|---|---|
| 2023-08-01 | 50000.00 |
Ця функція — база. Давай ускладнимо!
Створення більш складного звіту
Тепер уяви, що ми хочемо розбити продажі по клієнтах. Тобто, наш звіт має відображати:
- Клієнта
- Місяць
- Суму замовлень цього клієнта за місяць
Змінюємо процедуру
CREATE OR REPLACE FUNCTION customer_monthly_report(p_month DATE)
RETURNS TABLE (
customer_id INT,
month DATE,
total_sales NUMERIC(10, 2)
) AS $$
BEGIN
RETURN QUERY
SELECT
o.customer_id,
DATE_TRUNC('month', o.order_date) AS month,
SUM(o.total_amount) AS total_sales
FROM orders o
WHERE DATE_TRUNC('month', o.order_date) = DATE_TRUNC('month', p_month)
GROUP BY o.customer_id, DATE_TRUNC('month', o.order_date);
END;
$$ LANGUAGE plpgsql;
Тепер виклик процедури:
SELECT * FROM customer_monthly_report('2023-08-01');
І результат може бути таким:
| customer_id | month | total_sales |
|---|---|---|
| 101 | 2023-08-01 | 20000.00 |
| 102 | 2023-08-01 | 30000.00 |
Використовуємо тимчасові таблиці
Іноді при створенні складних звітів буває корисно використовувати тимчасові таблиці. Наприклад, якщо треба обробити проміжні дані.
CREATE OR REPLACE FUNCTION temp_table_example(p_month DATE)
RETURNS VOID AS $$
BEGIN
-- Створюємо тимчасову таблицю
CREATE TEMP TABLE temp_sales AS
SELECT
customer_id,
DATE_TRUNC('month', order_date) AS month,
SUM(total_amount) AS total_sales
FROM orders
WHERE DATE_TRUNC('month', order_date) = DATE_TRUNC('month', p_month)
GROUP BY customer_id, DATE_TRUNC('month', order_date);
-- Робимо додаткові розрахунки або маніпуляції з цією таблицею
-- Наприклад, виводимо топ-3 клієнтів за сумою замовлень
RAISE NOTICE 'Топ-3 клієнтів за місяць %:', p_month;
FOR record IN
SELECT customer_id, total_sales
FROM temp_sales
ORDER BY total_sales DESC
LIMIT 3
LOOP
RAISE NOTICE 'Клієнт: %, Сума: %', record.customer_id, record.total_sales;
END LOOP;
END;
$$ LANGUAGE plpgsql;
У цьому випадку тимчасова таблиця temp_sales використовується для зберігання проміжних результатів.
Корисні поради
- Оптимізація: використовуй індекси, щоб пришвидшити вибірки даних.
- Помилки з діленням на нуль: завжди перевіряй дільник, щоб не "завалити" звіт.
- Форматування дати: використовуй функції типу
TO_CHARдля зручного виводу.
Сподіваюсь, ти не дуже заснув! Попереду ще складніші й цікавіші задачі, тож не розслабляйся!
ПЕРЕЙДІТЬ В ПОВНУ ВЕРСІЮ