Doctrine 2 DQL - выберите строки, в которых поле "много ко многим" пуст?
У меня есть два класса в этом примере - DeliveryMethod и Country. Они имеют отношения "многие ко многим" друг с другом.
Что я хочу сделать, это выбрать все методы DeliveryMethods, у которых нет сопоставленных им стран.
Я могу сделать обратное, то есть выбрать все методы доставки, имеющие хотя бы одну страну -
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'
Ответы
Ответ 1
Как насчет этого? Предполагая, что $qb
является экземпляром построителя запросов
$qb->select('m')
->from('DeliveryMethods','m')
->leftJoin('m.countries','c')
->having('COUNT(c.id) = 0')
->groupBy('m.id');
Это даст вам методы DeliveryMethods, которые связаны со странами, и количество ассоциированных стран - 0
Ответ 2
Использовать Doctrine is empty
Он специально предназначен для проверки пустых ассоциаций:
$qb->select('m')->from('DeliveryMethods', 'm')->where('m.countries is empty')
Смотрите: Doctrine 2 ORM Documentation: Doctrine Query Language (поиск "пустой" )
Ответ 3
В объединениях и полях нет необходимости. Просто используйте функцию SIZE
:
$qb->select('m')
->from('DeliveryMethods','m')
->where('SIZE(m.countries) = 0');
Это даст вам все методы без прикрепленных стран.
Ответ 4
Невозможно присоединиться к значениям NULL, IIRC. Извинения за опечатку на twitter, должны были сказать "не могу".