Учение Symfony Присоединяйтесь и В запросе

0

Я хочу преобразовать SQL-запрос в DQL, и DQL поставляет странное поведение.

У меня этот SQL

SELECT b_t.id
Inner Join tag_to_entry AS b_te ON b_t.id = b_te.tag_id
WHERE b_te.entry_id IN (
    SELECT a_te.entry_id
    FROM entry AS a_e
    Inner Join tag_to_entry AS a_te ON a_e.id = a_te.entry_id
    Inner Join tag AS a_t ON a_t.id = a_te.tag_id
    WHERE a_t.id = 9
)
AND b_te.tag_id != 9
GROUP BY b_t.id
HAVING COUNT(b_te.tag_id) > 2

И это мой метод репозитория: (вот что я пробовал)

public function findRelatedTagsByTag(Tag $tag)
{
    $in = $this->getEntityManager()->getRepository('AppBundle:Entry')
        ->createQueryBuilder('a_e')
        ->where(':tag MEMBER OF a_e.tags');

    $qb = $this->createQueryBuilder("b_t");
    $qb->innerJoin('b_t.entries', 'b_te')
        ->where($qb->expr()->in('b_te', $in->getDQL()))
        // ->andWhere(':tag NOT MEMBER OF b_te.tags')
        // ->groupBy('b_t.id')
        // ->having('COUNT(b_te.tags) > 2')
        ->setParameters(array('tag' => $tag)); // Tag with ID: 9
    return $qb->getQuery()->getResult();
}

Если я вызову findRelatedTagsByTag() со всеми прокомментированными аргументами (например, выше), я получаю 9 записей (без каких-либо дубликатов). Если я сделаю то же самое с SQL (также без аргументов), он вернет 34 записи (с дубликатами).

Если я комментирую ->groupBy('b_t.id') то возвращается также 9 записей. В SQL только 9. Те же 9 записей, что и в методе репозитория.

И если я прокомментирую ->andWhere(':tag NOT MEMBER OF b_te.tags') в нем возвращается 0 записей. И в моих записях SQL 8, что правильно.

Параметр ->having('COUNT(b_te.tags) > 2') прокомментированный, генерирует исключение:

Ошибка: Недействительный вывод пути. StateFieldPathExpression или SingleValuedAssociationField ожидается


Я тестировал оба подзапроса, и они возвращают то же самое, поэтому нет ошибки. Я подозреваю, что группа DQL на ранней стадии и без моего заявления прокомментировала, и это происходит в этом странном поведении. Надеюсь, кто-нибудь сможет объяснить это и помочь мне.

Теги:
doctrine2

1 ответ

1
Лучший ответ

После 6 часов работы я, наконец, решил:

$qb ->innerJoin('b_t.entries', 'b_te')
    ->where($qb->expr()->in('b_te', $in->getDQL()))
    ->andWhere('b_t.id != :id')
    ->groupBy('b_t.id')
    ->having('COUNT(b_t.id) > 2')
    ->setParameters(array('tag' => $tag, 'id' => $tag->getId()));

->andWhere не нужен MEMBER OF и мне пришлось работать с идентификаторами.

Параметр ->having не использует таблицу отношений. Вместо этого он должен использовать объект репозитория.

Ещё вопросы

Сообщество Overcoder
Наверх
Меню