Порядок по количеству реляционных полей

#php #symfony #doctrine-orm

#php #symfony #доктрина-orm

Вопрос:

У меня есть следующие отношения:

Member один ко многим Product

Product многие к одному Member

Это запрос, который у меня есть, который работает:

 $qb = $this->createQueryBuilder('m');
$qb
    ->where('m.Authority = :Authority')
    ->setParameter('Authority', Authority::CREATOR)
    ->innerJoin('m.Product', 'p')
    ->select('COUNT(p) AS HIDDEN item_count', 'm')
    ->groupBy('m')
    ->orderBy("item_count", "ASC");
 

Однако, когда я добавляю дополнительные параметры для статуса продукта

 $qb = $this->createQueryBuilder('m');
$qb
    ->where('m.Authority = :Authority')
    ->setParameter('Authority', Authority::CREATOR)
    ->andWhere('p.Status = :Status')
    ->setParameter('Status', 1);
    ->innerJoin('m.Product', 'p')
    ->select('COUNT(p) AS HIDDEN item_count', 'm', 'p')
    ->groupBy('p')
    ->orderBy("item_count", "ASC");
 

Порядок по больше не выполняется. Я сбросил значение для item_count , и это всегда 1 так. Кто-нибудь сталкивался с такой же проблемой? Цель здесь — получить список участников с продуктами со статусом = 1, упорядоченными по количеству продуктов.

Редактировать: если я изменю groupBy('p') на groupBy('m') , он загрузит только один связанный Product для каждого Member

Комментарии:

1. хорошо … если вы группируете по продукту, очевидно, что количество продуктов всегда равно 1, и порядок работает нормально, потому что перед другими подсчетами больше не будет. кроме того, если вы группируете по m, все строки одного элемента сворачиваются, следовательно, вы получаете только один продукт p, но должны получить правильное количество продуктов. У меня такое чувство, что вы не совсем понимаете, как работает group by. короче говоря: только с одним соединением (и без подзапроса) вы не сможете получить как все отдельные продукты, так и количество продуктов в совокупности. вам нужно либо добавить другой запрос, либо другое соединение / подзапрос.

2. Спасибо тебе, @Jakumi. Ваш комментарий помог мне двигаться в правильном направлении. Я дал ответ на свой собственный вопрос. Хотя у меня это работает, есть еще кое-что, что меня озадачивает. Может быть, ты сможешь помочь мне разобраться в этом еще немного.

Ответ №1:

Для всех, кто боролся с той же проблемой, вот как я это сделал:

 $qb = $this->createQueryBuilder('m');
$qb
    ->where('m.Authority = :Authority')
    ->setParameter('Authority', Authority::CREATOR)
    ->andWhere('p.Status = :Status')
    ->setParameter('Status', 1);
    ->select('p, m')
    ->addSelect('(SELECT COUNT(DISTINCT p1)
    FROM EccubeEntityMember m1
    INNER JOIN EccubeEntityProduct p1
    WHERE m1.Authority = ' . Authority::CREATOR . ' AND p1.Status = 1 AND p1.Creator = m.id
    ) AS hidden item_count')
    ->innerJoin('m.Product', 'p')
    ->groupBy('p')
    ->orderBy("item_count", "ASC");
 

Это работает, но я не понимаю, почему это так p1.Creator = m.id ? Если я использую m1.id его, он просто суммирует количество элементов.

Редактировать: добавлен обновленный код после комментария Джакуми относительно объединения. Несмотря на то, что оба кода работают, второй имеет больше смысла.

 $qb = $this->createQueryBuilder('m');
$qb
    ->where('m.Authority = :Authority')
    ->setParameter('Authority', Authority::CREATOR)
    ->andWhere('p.Status = :Status')
    ->setParameter('Status', 1);
    ->select('p, m')
    ->addSelect('(SELECT COUNT(DISTINCT p1)
    FROM EccubeEntityMember m1
    INNER JOIN m1.Product p1
    WHERE m1.Authority = ' . Authority::CREATOR . ' AND p1.Status = 1 AND p1.Creator = m
    ) AS hidden item_count')
    ->innerJoin('m.Product', 'p')
    ->groupBy('p')
    ->orderBy("item_count", "ASC");
 

Комментарии:

1. дело в том, что этот подзапрос-select без m1 вместо m не имеет отношения к основному запросу., затем он будет считать все продукты для всех членов. ваше соединение немного странное, возможно, вы пытались inner join m1.Product p1 . вам может сойти с рук отсутствие m1 вообще и просто сказать p1.creator = m tbh. но я не совсем уверен, сколько doctrine orm знает о сущностях и сколько магии происходит; o)