В этом примере у меня есть два класса – DeliveryMethod и Country. У них есть много-много отношений друг с другом.
Что я хочу сделать, это выбрать все методы доставки, которые не имеют каких-либо стран, сопоставленных с ними.
Я могу сделать обратное, то есть выбрать все методы доставки, в которых есть как минимум одна страна –
SELECT m FROM DeliveryMethod m JOIN m.countries
Но я не могу понять, как это сделать, выберите, где поле стран пусто. В простом SQL я бы сделал следующее (deliverymethod_country – таблица ссылок):
SELECT m.* FROM deliverymethods m LEFT JOIN deliverymethod_country dc ON dc.deliverymethod_id = m.id WHERE dc.deliverymethod_id IS NULL
Однако любой эквивалент DQL этого не работает, например:
SELECT m FROM DeliveryMethod m LEFT JOIN m.countries WHERE m.countries IS NULL
Который дает мне эту ошибку:
[Syntax Error] line 0, col 75: Error: Expected end of string, got 'm'
Как насчет этого? Предполагая, что $qb
– ваш экземпляр построителя запросов
$qb->select('m') ->from('DeliveryMethods','m') ->leftJoin('m.countries','c') ->having('COUNT(c.id) = 0') ->groupBy('m.id');
Это даст вам методы DeliveryMethods, которые связаны со странами, и количество ассоциированных стран – 0
is empty
Он специально предназначен для проверки пустых ассоциаций:
$qb->select('m')->from('DeliveryMethods', 'm')->where('m.countries is empty')
См .: Doctrine 2 ORM Documentation: Doctrine Query Language (поиск «пусто»)
В объединениях и жилых домах нет необходимости. Просто используйте функцию SIZE
:
$qb->select('m') ->from('DeliveryMethods','m') ->where('SIZE(m.countries) = 0');
Это даст вам все методы без привязанных стран
Невозможно присоединиться к значениям NULL, IIRC. Извинения за опечатку на твиттере должны были сказать «не могу».