Какой у вас опыт написания сложных SQL-запросов?

«Какой у вас опыт написания сложных SQL-запросов?» — вопрос из категории Базы данных, который задают на 10% собеседований Java Разработчик. Ниже — развёрнутый ответ с разбором ключевых моментов.

Ответ

Имею опыт написания и оптимизации сложных SQL-запросов (PostgreSQL, MySQL) и их аналогов в JPA (JPQL, Criteria API).

Пример сложного SQL-запроса с JOIN, агрегацией и подзапросом:

SELECT 
    u.id,
    u.name,
    COUNT(o.id) AS total_orders,
    (SELECT MAX(amount) FROM payments p WHERE p.user_id = u.id) AS max_payment
FROM users u
LEFT JOIN orders o ON u.id = o.user_id AND o.status = 'COMPLETED'
WHERE u.created_at > '2023-01-01'
GROUP BY u.id, u.name
HAVING COUNT(o.id) > 5
ORDER BY total_orders DESC;

Ключевые навыки и best practices:

  • Оптимизация: Анализ плана выполнения (EXPLAIN ANALYZE), создание эффективных индексов, избегание N+1 проблемы.
  • Сложные конструкции: Оконные функции (ROW_NUMBER(), RANK(), LAG/LEAD), рекурсивные CTE (WITH RECURSIVE), UNION.
  • Работа в JPA/Hibernate:
    • Использование @EntityGraph или JOIN FETCH для жадной загрузки и решения N+1.
    • Criteria API для построения динамических, типобезопасных запросов.
    • Проекции DTO через @Query и конструктор выражений для выборки только нужных данных, минуя лишнюю работу контекста persistence.
  • Безопасность и работа с данными: Всегда использую параметризованные запросы (защита от SQL-инъекций), пагинацию (LIMIT/OFFSET, keyset pagination) для больших наборов данных.