使用 Symfony 3.4 和 Doctrine 在 MySql 数据库上获取没有加倍 属性 值的不同行

Fetch distinct rows without doubled property values on MySql DB with Symfony 3.4 and Doctrine

在 Symfony 3.4 应用程序中,我有一个具有 4 个属性和 ID 的实体。

它由 mySql 数据库上的学说管理。

说出名为 p1、p2、p3 和 q 的属性。 示例数据库 table 可能是这样的:

id  p1  p2  p3  q
------------------
1   x   y   z   1
2   x   y   n   2
3   x       z   1
4   x       z   2
5   x   y   z   3
6   x   y   z   4
7   x   n   z   1

我需要做的是请求数据库中具有不同 p1、p2、p3 组合的所有实体。 所以使用给定的示例数据库 table 我需要的结果是

id  p1  p2  p3  q
------------------
1   x   y   z   1
2   x   y   n   2
3   x       z   1
7   x   n   z   1

因此,id 为 4、5 和 6 的行不会在集合中,因为它们具有 p1、p2、p3 的 "doubled" 组合。

现在 - 我如何使用 Symfony 3.4 的存储库 class 上的方法来执行此操作,如下所述:

https://symfony.com/doc/3.4/doctrine.html

或者有没有其他方法可以实现我想要的?

非常欢迎任何提示。

编辑: 基本上我正在寻找 p1、p2、p3 的所有现有组合的列表,而没有在列表中加倍的组合。结果集中返回哪一行并不重要(关于属性 id 和 q),只要包含 p1、p2、p3 的每个组合的一行(且仅包含一行)即可。

一个"group by"子查询来消除重复数据,一个主查询从ids中搜索:

$dql = 'SELECT r FROM myTable r
WHERE r.id IN (
    SELECT min(s.id) FROM myTable s
    GROUP BY s.p1, s.p2, s.p3
)';

$rows = $em->createQuery($dql)
    ->getResult();

如果您只想要 p1p2p3 的不同组合而不关心 idq,您可以将它们从您的查询中排除并使用不同的子句。

存储库 class 没有内置方法满足您的需要,您可能想创建一个 custom repository class(我每次必须为我的自定义查询编写自定义查询时都会亲自这样做实体)

让我们考虑一下您的实体(位于 src/AppBundle/Entity/MyEntity.php 中的示例)是这样声明的:

namespace AppBundle\Entity;

use Doctrine\ORM\Mapping as ORM;

/**
 * @ORM\Entity(repositoryClass="AppBundle\Repository\MyEntityRepository")
 */
class MyEntity
{
    //declarations of $id, $p1 and so on...
}

您可以使用一种方法创建自定义存储库 class(例如 src/AppBundle/Repository/MyEntityRepository.php)以获得所需的结果:

namespace AppBundle\Repository;

use Doctrine\ORM\EntityRepository;

class MyEntityRepository extends EntityRepository
{
    public function findAllUniqueCombinations()
    {
        $result = $this->createQueryBuilder('m')
                       ->select('m.p1 p1', 'm.p2 p2', 'm.p3 p3')
                       ->distinct()
                       ->getQuery()
                       ->getResult();

        return ($result);
    }
}

并且,在某些控制器操作中:

$MyCombinationList = $this->getDoctrine()
                          ->getManager()
                          ->getRepository(MyEntity::class)
                          ->findAllUniqueCombinations();

我使用完全相同的查询进行测试(只有 select() 改变了)

输入数据

id | name       | firstname
---+------------+---------- 
 1 | Smith      | John 
 2 | Smith      | John 
 3 | Smith      | John 
 4 | Smith      | John 
 5 | Doe        | Jane 
 6 | Connor     | Sarah 
 7 | The Sponge | Bob 
 8 | Marley     | Bob

select 是 ->select('c.name name', 'c.firstname firstname')

输出 var_dump($result); 给出:

array (size=5)
  0 => 
    array (size=2)
      'name' => string 'Smith' (length=5)
      'firstname' => string 'John' (length=4)
  1 => 
    array (size=2)
      'name' => string 'Doe' (length=3)
      'firstname' => string 'Jane' (length=4)
  2 => 
    array (size=2)
      'name' => string 'Connor' (length=6)
      'firstname' => string 'Sarah' (length=5)
  3 => 
    array (size=2)
      'name' => string 'The Sponge' (length=9)
      'firstname' => string 'Bob' (length=3)
  4 => 
    array (size=2)
      'name' => string 'Marley' (length=6)
      'firstname' => string 'Bob' (length=3)