У меня есть объект 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)"
Я пробовал, но это действительно приводит к той же проблеме.
Не могли бы вы отредактировать свой вопрос с помощью var_dump($query->getSQL())
Дамп добавлен
Пожалуйста, в вопросах по коду дайте минимальный воспроизводимый пример - код вырезания, вставки и выполнения, а также желаемый результат, а также четкую спецификацию и объяснение. Это включает в себя наименьший код, который вы можете дать, то есть код, который, как вы показываете, в порядке, расширенный кодом, который вы показываете, не в порядке. (Основная отладка.) PS Re «Но я пропускаю рекламу, например, у которой нет записи NL adRemaks, но есть запись EN или DE». Но вы запрашиваете язык NL или NULL. Вы также четко не говорите нам, какие строки вам нужны; вы просто даете неправильный код и в одну сторону это неправильно. Вам нужно «или rem.adRemark равно null» вместо «или rem.language равно null»?
Я согласен с филиппи. Пока я могу только представить, что вы хотите предпочесть примечания NL, но ваш запрос ограничивает его примечаниями NL (и теми примечаниями, где язык установлен на NULL, что, как я полагаю, невозможно). таким образом исключая примечания на других языках (и при отсутствии примечания NL, связанные с ними объявления).
Верно, я предпочитаю примечания NL, но теперь я пропускаю объявления, в которых нет примечания NL, но есть другое примечание, например EN или DE. Примечание к этим отсутствующим объявлениям может иметь значение NULL, что не является проблемой, но полное объявление отсутствует в запросе.
Вы хотите фильтровать не весь набор результатов, а только при соединении, поэтому переместите условие в оговорка о присоединении.
Измените запрос на:
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 Хороший вопрос, держу пари, есть несколько способов сделать это. Пожалуйста, если вы не возражаете, создайте новый вопрос об этом, и я обязательно постараюсь помочь.
Я добавил новый вопрос, надеюсь, вы поможете.. stackoverflow.com/questions/55715353/…
Вы пробовали
innerJoin
вместо этого? Или это приводит к той же проблеме?