Imagine i have a entity Person
which has a many-to-many relation with Vehicle
How can i find another Person exactly having the same Vehicles?
Example:
Person 1 (ID=1) has vehicle with id 5,6 and 7
Person 2 (ID=2) has vehicles with id 5,6,8 -> should not match with person 1!
Person 3 (ID=3) has vehicle with id 5 ->should not match with person 1!
Person 4 (ID=4) has vehicles with id 5,6 and 7 -> should match with person 1
Person 5 (ID=5) has vehicles with id 5,6 and 7 -> should match with person 1 and person 4
So what is the DQL expression for that?
I tried already with "IN" but this will also match even if just one of my id's match.
Thanks
Clean DQL
:
$query = $entityManager->createQuery("
SELECT p, pv
FROM Person p
INNER JOIN p.vehicles pv
WHERE pv.id in (
SELECT v.id
FROM Vehicle v
INNER JOIN v.persons vp
WHERE p.id <> vp.id
) GROUP BY p.id
HAVING count(pv.id) > 1");
$persons = $query->getResult();
Explanation : To get persons with same vehicles, you need to get vehicles, that equal to person's, but attached to other. HAVING
regulates count of minimal same vehicles, by which we group persons in collection.
You can use more flexible approach with PHP
, that get only persons with full identical vehicles. Steps:
Code :
<?php
$query = $entityManager->createQuery("select p,v from Person p JOIN p.vehicles v");
$persons = $query->getArrayResult();
$personsIdsWithSameVehicles = [];
foreach ($persons as $person) {
$vehiclesIds = array_column($person['vehicles'], 'id');
$subPersons = array_filter($persons, function($filterPerson) use ($person) {
if($filterPerson['id'] != $person['id']) return $filterPerson;
});
foreach ($subPersons as $subPerson) {
$subVehiclesIds = array_column($subPerson['vehicles'], 'id');
if(count($vehiclesIds) == count($subVehiclesIds) and
empty(array_diff($vehiclesIds, $subVehiclesIds))) {
$personsIdsWithSameVehicles[] = $person['id'];
break;
}
}
}
$personsQuery = $entityManager->createQuery("select p from Person p where p.id IN(:persons)");
$personsQuery->setParameter('persons', $personsIdsWithSameVehicles);
$personsWithSameVehicles = $personsQuery->getResult();
The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.