Встроенные функции и пользовательские функции (UDF)
🧩 Функции в SQL: твой универсальный инструментарий
Функции в SQL — это как швейцарский нож аналитика: они режут, сортируют, преобразуют и анализируют данные одним движением. В SQL есть два типа функций: встроенные (те, что уже «в коробке») и пользовательские (UDF, которые ты создаёшь сам). Давай разберём оба вида!
🔧 Встроенные функции: готовые решения под капотом
Встроенные функции делятся на три группы:
1. Скалярные функции — работают с отдельными значениями
-- Приводим текст к верхнему регистру
SELECT UPPER('hello') AS shout; -- HELLO
-- Округляем число
SELECT ROUND(3.14159, 2) AS pi; -- 3.14
-- Извлекаем часть строки
SELECT SUBSTRING('2023-10-15', 6, 2) AS month; -- 10
2. Агрегатные функции — сводят множество значений к одному
-- Средняя цена товаров в категории
SELECT
category,
AVG(price) AS avg_price
FROM products
GROUP BY category;
-- Количество уникальных пользователей
SELECT COUNT(DISTINCT user_id) FROM orders;
3. Оконные функции — аналитика без группировки
-- Рейтинг товаров по продажам в каждой категории
SELECT
product_name,
category,
SUM(quantity) AS total_sales,
RANK() OVER(PARTITION BY category ORDER BY SUM(quantity) DESC) AS rank
FROM sales
GROUP BY product_name, category;
🛠️ Пользовательские функции (UDF): когда стандартного недостаточно
Представь, что тебе нужно рассчитать НДС для каждого товара в базе. Вместо повторения формулы в каждом запросе, создай UDF:
Пример в PostgreSQL:
CREATE OR REPLACE FUNCTION calculate_vat(price NUMERIC, rate NUMERIC)
RETURNS NUMERIC AS $$
BEGIN
RETURN price * rate / 100;
END;
$$ LANGUAGE plpgsql;
-- Использование:
SELECT
product_name,
price,
calculate_vat(price, 20) AS vat
FROM products;
А вот хитрость от Данилы Бежина:
«Используй UDF для сложных бизнес-правил — так ты избежишь дублирования кода и сделаешь логику прозрачной».
💡 Когда использовать UDF? Практические кейсы
1. Сложные расчёты:
-- Расчёт аннуитетного платежа
CREATE FUNCTION annuity_payment(sum NUMERIC, rate NUMERIC, term INT) ...
2. Частые преобразования данных:
-- Приведение телефонов к единому формату
CREATE FUNCTION format_phone(raw_phone TEXT) ...
3. Кастомная валидация:
-- Проверка email без регулярных выражений
CREATE FUNCTION is_valid_email(email TEXT) RETURNS BOOLEAN ...
⚡ Производительность: скрытая цена UDF
UDF — это мощно, но: - Вычисляются на стороне сервера — могут тормозить на больших данных - Сложно оптимизируются — движок БД не всегда «понимает» их логику - Альтернатива: CTE (WITH) или подзапросы для простых случаев
Лайфхак: для часто используемых UDF делай детерминированными (добавляй IMMUTABLE в PostgreSQL), если это возможно.
🎓 Главное, что нужно запомнить
- Встроенные функции — твои лучшие друзья для повседневных задач
- UDF — создавай для сложной бизнес-логики и повторяющихся операций
- Тестируй UDF на реалистичных данных перед использованием в продакшене
- Агрегатные и оконные функции — ключ к аналитике без боли
Теперь твоя очередь! Попробуй создать UDF для расчёта дисконтированной стоимости — это отличное упражнение для старта. 🚀