教义/ DQL获得具有完全相同的相关实体的实体

时间:2018-08-22 14:40:16

标签: php doctrine dql

假设我有一个实体Person,它与Vehicle有多对多的关系

我如何找到另一个完全具有相同车辆的人?

示例:

人1(ID = 1)的车辆ID为5,6和7

人员2(ID = 2)的车辆ID为5,6,8->不能与人员1匹配!

第3个人(ID = 3)的车辆ID为5->与第1个人不匹配!

第4个人(ID = 4)的车辆ID为5,6和7->应该与第1个人匹配

第5个人(ID = 5)的ID为5,6和7的车辆->应该与第1个人和第4个人匹配

那DQL表达式是什么?

我已经尝试过使用“ IN”,但这也将匹配,即使只是我的ID的匹配项之一。

谢谢

1 个答案:

答案 0 :(得分:0)

清洁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();

说明: 要使人拥有相同的车辆,您需要获得与人的车辆相同但又与其他车辆相连的车辆。 HAVING规定了最少的相同车辆的数量,我们以此将车辆归类。

您可以对PHP使用更灵活的方法,该方法只让拥有完全相同车辆的人使用。步骤:

  1. 让所有有车辆的人
  2. 比较车辆ID
  3. 仅将具有相同车辆的人员ID添加到结果中
  4. 收集有相同车辆的人

代码

<?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();
相关问题