Конструктор запросов с И и ИЛИ

Я работаю в Symfony 3.4 гибкий, мне нужно сделать один построитель запросов следующим образом:

Все медиа с "опубликовано" в True И медиа ТИП :type AND ((condition 1) OR (condition 2) OR (condition 3)) с построителем запросов symfony доктрины. Эти 2 условия уже выполняются (опубликовано и экземпляр :instance):

 $queryBuilder = $this->createQueryBuilder('m')
        ->chere('m.published = :published')
        ->andWhere('m INSTANCE OF :instance');

/* 
WHERE m.published = true AND m INSTANCE OF :instance

AND (
    //    ('m.startDate <= :today AND m.endDate >= :today')
    // OR ('m.startDate IS NULL AND m.endDate >= :today')
    // OR ('m.startDate IS NULL AND m.endDate IS NULL')
    // OR ('m.startDate <= :today AND m.endDate IS NULL')
*/

Когда я пытаюсь что-то вроде:

$queryBuilder->andWhere($queryBuilder->expr()->andX(
            $queryBuilder->expr()->lte('m.startDate', ':today'),
            $queryBuilder->expr()->gte('m.endDate', ':today'))
   );

Но это не работает, он возвращает что-то вроде:

WHERE (
    (m.published = 1 AND m.type IN (:type)) // I already needed this in all cond
    AND m.start_date <= :today AND m.end_date >= :today // cond 1
)

    OR (m.start_date IS NULL :today AND m.end_date IS NULL) // cond 2
    OR ... // cond 3

Так что мое состояние с ((m.published = 1 AND m.type IN (:type))) должно быть во всех условиях не только первое

Есть ли у вас какие-либо идеи ?

Спасибо.

Стоит ли изучать PHP в 2026-2027 годах?
Стоит ли изучать PHP в 2026-2027 годах?
Привет всем, сегодня я хочу высказать свои соображения по поводу вопроса, который я уже много раз получал в своем сообществе: "Стоит ли изучать PHP в...
Symfony Station Communiqué - 7 июля 2023 г
Symfony Station Communiqué - 7 июля 2023 г
Это коммюнике первоначально появилось на Symfony Station .
Symfony Station Communiqué - 17 февраля 2023 г
Symfony Station Communiqué - 17 февраля 2023 г
Это коммюнике первоначально появилось на Symfony Station , вашем источнике передовых новостей Symfony, PHP и кибербезопасности.
Управление ответами api для исключений на Symfony с помощью KernelEvents
Управление ответами api для исключений на Symfony с помощью KernelEvents
Много раз при создании api нам нужно возвращать клиентам разные ответы в зависимости от возникшего исключения.
0
0
3 465
2
Перейти к ответу Данный вопрос помечен как решенный

Ответы 2

Ответ принят как подходящий

Ты можешь это сделать:

 $queryBuilder = $this->createQueryBuilder('m')
        ->where("((m.published = true AND m INSTANCE OF :instance) AND
                      (
                          (m.startDate <= :today AND m.endDate >= :today) OR
                          (m.startDate IS NULL AND m.endDate >= :today) OR
                          (m.startDate IS NULL AND m.endDate IS NULL) OR
                          (m.startDate <= :today AND m.endDate IS NULL)
                      )
                 )"
               );

Насколько вам известно, с DQL это будет так:

//Important to have it initialized alone so you can use it for expressions
$qb=$this->createQueryBuilder('m');

$qb->andWhere($qb->expr()->andX(
    "m.published=1",
    "m INSTANCE OF :instance",
    $qb->expr()->orX(
        $qb->expr()->andX("m.startDate <= :today", "m.endDate >= :today"),
        $qb->expr()->andX("m.startDate IS NULL", "m.endDate >= :today"),
        $qb->expr()->andX("m.startDate IS NULL", "m.endDate IS NULL"),
        $qb->expr()->andX("m.startDate <= :today", "m.endDate IS NULL")
    )
))
->setParameters(array(
    'instance'=>$instance,
    'today'=>$today,
))
->getQuery()
->execute();

Это даст вам следующий запрос DQL:

SELECT m
FROM AppBundle\Entity\Media m
WHERE m.published=1
    AND m INSTANCE OF :instance
    AND ((m.startDate <= :today AND m.endDate >= :today)
        OR (m.startDate IS NULL AND m.endDate >= :today)
        OR (m.startDate IS NULL AND m.endDate IS NULL)
        OR (m.startDate <= :today AND m.endDate IS NULL))

Некоторые советы:

Никогда не используйте where() или orWhere, это обязательно когда-нибудь создаст вам проблемы
Подробнее об этом можно прочитать здесь

Всегда используйте двойные кавычки для вашего запроса. Doctrine будет принимать только одинарные кавычки для строк в запросе

Спасибо за все уточнения, это действительно интересно и полезно =)

keegzer 11.04.2019 14:25

Другие вопросы по теме