Doctrine 2 DQL – выберите строки, в которых поле «много ко многим» пуст?

В этом примере у меня есть два класса – 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

Использовать Doctrine 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. Извинения за опечатку на твиттере должны были сказать «не могу».