Метка: оптимизация запросов

  • Как работать с GROUP BY и SUM в Doctrine

    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-запросы
    • Тестируйте запросы на реальных данных