Конструктор запросов Doctrine возвращает не все записи в отношении один ко многим с помощью leftJoin

У меня есть объект Ad, который представляет рекламу. Этот объект Ad имеет слишком много отношений с adRemark. Причина для этого заключается в том, что adRemark содержит несколько записей из-за поддержки нескольких языков.

Объявление может иметь только один adRemark для каждого языка, но может отсутствовать записи для языка, которые не заполнены, или может даже не иметь записи adRemark, поскольку никакие языковые данные не заполнены.

Я создаю запрос, который извлекает все объявления, включая adRemark.

       $query = $this->createQueryBuilder('ad')
            ->select('ad.id, ad.title, ad.year, ad.hours, ad.status')
            ->addSelect('rem.remark')
            ->leftJoin('ad.remark', 'rem')    
            ->andWhere("rem.language = 'NL' or rem.language is null")
            ->getQuery()
            ->getResult();

С помощью этого запроса я получаю все объявления, в которых, например, заполнено примечание на голландском (NL) или нет записей adRemark. Но мне не хватает рекламы, у которой, например, нет записи NL adRemaks, но есть запись EN или DE.

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

Вот дамп sql:

"SELECT ad.id, ad.title, ad.year, ad.hours, ad.status, rem.remark FROM Mtr\Bundle\Entity\Ad LEFT JOIN ad.remark rem WHERE (rem.language = 'NL' or rem.language is null)"

Вы пробовали innerJoin вместо этого? Или это приводит к той же проблеме?

Fabian Schmick 08.04.2019 16:34

Я пробовал, но это действительно приводит к той же проблеме.

Tom 08.04.2019 16:35

Не могли бы вы отредактировать свой вопрос с помощью var_dump($query->getSQL())

Fabian Schmick 08.04.2019 16:38

Дамп добавлен

Tom 08.04.2019 16:46

Пожалуйста, в вопросах по коду дайте минимальный воспроизводимый пример - код вырезания, вставки и выполнения, а также желаемый результат, а также четкую спецификацию и объяснение. Это включает в себя наименьший код, который вы можете дать, то есть код, который, как вы показываете, в порядке, расширенный кодом, который вы показываете, не в порядке. (Основная отладка.) PS Re «Но я пропускаю рекламу, например, у которой нет записи NL adRemaks, но есть запись EN или DE». Но вы запрашиваете язык NL или NULL. Вы также четко не говорите нам, какие строки вам нужны; вы просто даете неправильный код и в одну сторону это неправильно. Вам нужно «или rem.adRemark равно null» вместо «или rem.language равно null»?

philipxy 08.04.2019 18:00

Я согласен с филиппи. Пока я могу только представить, что вы хотите предпочесть примечания NL, но ваш запрос ограничивает его примечаниями NL (и теми примечаниями, где язык установлен на NULL, что, как я полагаю, невозможно). таким образом исключая примечания на других языках (и при отсутствии примечания NL, связанные с ними объявления).

Jakumi 08.04.2019 20:41

Верно, я предпочитаю примечания NL, но теперь я пропускаю объявления, в которых нет примечания NL, но есть другое примечание, например EN или DE. Примечание к этим отсутствующим объявлениям может иметь значение NULL, что не является проблемой, но полное объявление отсутствует в запросе.

Tom 08.04.2019 22:57
Стоит ли изучать PHP в 2023-2024 годах?
Стоит ли изучать PHP в 2023-2024 годах?
Привет всем, сегодня я хочу высказать свои соображения по поводу вопроса, который я уже много раз получал в своем сообществе: "Стоит ли изучать 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 нам нужно возвращать клиентам разные ответы в зависимости от возникшего исключения.
1
7
697
1
Перейти к ответу Данный вопрос помечен как решенный

Ответы 1

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

Вы хотите фильтровать не весь набор результатов, а только при соединении, поэтому переместите условие в оговорка о присоединении.

Измените запрос на:

use Doctrine\ORM\Query\Expr\Join;

$query = $this->createQueryBuilder('ad')
        ->select('ad.id, ad.title, ad.year, ad.hours, ad.status')
        ->addSelect('rem.remark')
        ->leftJoin('ad.remark', 'rem', Join::WITH, "rem.language = 'NL' OR rem.language is null")
        ->getQuery()
        ->getResult();

использованная литература

Как заставить язык NL работать! Можно ли также в условном соединении получить язык EN, только если язык NL не выходит, иначе возвращается язык NL?

Tom 16.04.2019 12:11

@Tom Хороший вопрос, держу пари, есть несколько способов сделать это. Пожалуйста, если вы не возражаете, создайте новый вопрос об этом, и я обязательно постараюсь помочь.

Jannes Botis 16.04.2019 19:08

Я добавил новый вопрос, надеюсь, вы поможете.. stackoverflow.com/questions/55715353/…

Tom 16.04.2019 21:26

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