使用Symfony 3.4和Doctrine在MySql DB上获取不同的行,但属性值不加倍

使用Symfony 3.4和Doctrine在MySql DB上获取不同的行,但属性值不加倍,symfony,doctrine-orm,doctrine,symfony-3.4,symfony3.x,Symfony,Doctrine Orm,Doctrine,Symfony 3.4,Symfony3.x,在Symfony 3.4应用程序中,我有一个具有4个属性和id的实体 它由mySql数据库上的条令管理 说出命名为p1、p2、p3和q的属性。 示例DB表可以如下所示: 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 我

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

它由mySql数据库上的条令管理

说出命名为p1、p2、p3和q的属性。 示例DB表可以如下所示:

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不同组合的所有实体。 因此,使用给定的示例DB表,我需要的结果是

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组合“加倍”

现在-如何使用Symfony 3.4的Repository类上的方法执行此操作,如下所述:

或者有没有其他的方法来实现我想要的

欢迎任何提示

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

用于消除重复数据的“分组依据”子查询,以及用于从id搜索的主查询:

$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();

如果您只需要
p1
p2
p3
的different unique组合,而不关心
id
q
,则可以从查询中排除它们,并使用distinct子句

对于您的需要,没有存储库类的内置方法,您可能希望创建一个(每次我必须为我的实体编写自定义查询时,我都会亲自创建)

让我们考虑您的实体(位于示例中的代码> SRC/AppBundle /Mult/MySturnal.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...
}
您可以使用方法创建自定义存储库类(例如
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('c.name name','c.firstname firstname')

输出
var\u 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)

在您的示例中,
p1
p2
p3
在索引1和5处的值相同。关于
id
q
的值有哪些标准?到目前为止你试过什么吗?@Cid谢谢,这是真的-我编辑了我的问题来修正错误的目标集。没有id和q的标准。Id只是自动递增的唯一行Id,q是另一个属性,它允许在p1、p2、p3的相同组合上存储q的多个不同值。我需要的是查询p1、p2、p3的所有不同组合,但如果一个组合存在两次或更多次,则在结果列表中只得到一个命中率(我不在乎我得到了哪个命中率)。我的意思是,为什么在查询中
1 x y z 1
优先于
5 x y z 3
6 x y z 4
?@Cid不优先选择所选行-它只是表中的第一行。我只是在寻找p1、p2、p3的所有现有组合的完整列表。请参见问题中我的编辑。尽管@Guillaume的回答也是正确的,但我选择您的回答是正确的,因为我喜欢关于存储库类的其他信息。使用dql查询生成器方法似乎是受鼓励的方法,而不是字符串表示法。我用这种方式实现了它,效果非常好。谢谢。我刚刚注意到,通过这种方式,我没有得到MyEntity对象的数组,而是从DB中得到一个带有纯结果列表的数组。如何让它返回MyEntity类型的对象数组?我认为所有从repository类继承的find方法都会这样做,不是吗?这是因为您得到的是该实体的一些字段,而不是整个实体,因此无法构建对象,因此需要一个数组数组。看看好的,我明白了。谢谢你。我没有测试它,但我想如果我需要这些东西,它会帮助我:-)谢谢。我认为这是正确的。我之所以将@Cid s answere标记为正确答案,只是因为它添加了一些我也可以使用的信息,而且使用dql查询生成器方法似乎比字符串表示法更受欢迎。@user3440145毫不犹豫地对他的答案进行投票,即使您没有将其标记为已解决,这是令人鼓舞的