Doctrine ORM предоставляет мощные инструменты для работы с агрегатными функциями SQL. В этом руководстве мы разберем использование GROUP BY и SUM в Symfony-проектах.
1. Базовые примеры
1.1. Простая группировка с суммированием
// ProductRepository.php
public function getCategoryStats()
{
return $this->createQueryBuilder('p')
->select([
'p.category',
'SUM(p.price) as total_price',
'COUNT(p.id) as product_count'
])
->groupBy('p.category')
->getQuery()
->getResult();
}
1.2. Группировка по дате
public function getMonthlySales()
{
return $this->createQueryBuilder('o')
->select([
"DATE_FORMAT(o.createdAt, '%Y-%m') as month",
'SUM(o.total) as sales'
])
->groupBy('month')
->getQuery()
->getResult();
}
2. Продвинутые сценарии
2.1. Фильтрация с HAVING
public function getHighValueOrders($minAmount)
{
return $this->createQueryBuilder('o')
->select([
'c.name',
'SUM(o.total) as total'
])
->join('o.customer', 'c')
->groupBy('c.id')
->having('total > :minAmount')
->setParameter('minAmount', $minAmount)
->getQuery()
->getResult();
}
2.2. Группировка с JOIN связанных сущностей
public function getSalesByCategoryAndUser()
{
return $this->createQueryBuilder('o')
->select([
'p.category',
'u.name',
'SUM(o.total) as total'
])
->join('o.product', 'p')
->join('o.user', 'u')
->groupBy('p.category, u.id')
->getQuery()
->getResult();
}
3. Оптимизация запросов
- Добавляйте индексы для полей группировки
- Используйте кеширование для сложных отчетов
- Ограничивайте выборку при работе с большими данными
4. Частые проблемы
Проблема | Решение |
---|---|
Ошибка «Non-selected field in GROUP BY» | Включите все неагрегированные поля в GROUP BY |
Медленные запросы | Добавьте индексы и используйте LIMIT |
Заключение
GROUP BY и SUM в Doctrine — мощные инструменты для аналитики. Ключевые правила:
- Используйте индексы для полей группировки
- Для сложных отчетов применяйте нативные SQL-запросы
- Тестируйте запросы на реальных данных
Добавить комментарий