Doctrine 2 DQL - Select rows where a many-to-many

2019-01-25 03:59发布

I have two classes in this example - DeliveryMethod and Country. They have a many-to-many relationship with each other.

What I want to do is select all DeliveryMethods that do not have any Countries mapped to them.

I can do the opposite, that is select all delivery methods that have at least one country -

SELECT m FROM DeliveryMethod m JOIN m.countries

But I can't figure out how to do select where the countries field is empty. In plain SQL I would do the following (deliverymethod_country is the linking table):

SELECT m.* FROM deliverymethods m
LEFT JOIN deliverymethod_country dc ON dc.deliverymethod_id = m.id
WHERE dc.deliverymethod_id IS NULL

However any DQL equivalent of this doesn't work, for example:

SELECT m FROM DeliveryMethod m LEFT JOIN m.countries WHERE m.countries IS NULL

Which gives me this error:

[Syntax Error] line 0, col 75: Error: Expected end of string, got 'm'

标签: php doctrine dql
4条回答
爱情/是我丢掉的垃圾
2楼-- · 2019-01-25 04:16

There is no need in joins and havings. Simply use SIZE function:

$qb->select('m')
   ->from('DeliveryMethods','m')
   ->where('SIZE(m.countries) = 0');

This will give you all methods without attached countries

查看更多
地球回转人心会变
3楼-- · 2019-01-25 04:27

Use Doctrine's is empty

It's specifically designed to check for empty associations:

$qb->select('m')->from('DeliveryMethods', 'm')->where('m.countries is empty')

See: Doctrine 2 ORM Documentation: Doctrine Query Language (search for "is empty")

查看更多
可以哭但决不认输i
4楼-- · 2019-01-25 04:31

What about this? Assuming $qb is your query builder instance

$qb->select('m')
   ->from('DeliveryMethods','m')
   ->leftJoin('m.countries','c')
   ->having('COUNT(c.id) = 0')
   ->groupBy('m.id');

This would give you the DeliveryMethods which is associated with countries and count of the associated countries is 0

查看更多
Explosion°爆炸
5楼-- · 2019-01-25 04:38

Can't join NULL values, IIRC. Apologies for the typo on twitter, should have said "can't".

查看更多
登录 后发表回答