使用Symfony 3.4和Doctrine在MySql DB上获取不同的行,但属性值不加倍
在Symfony 3.4应用程序中,我有一个具有4个属性和id的实体 它由mySql数据库上的条令管理 说出命名为p1、p2、p3和q的属性。 示例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 我
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毫不犹豫地对他的答案进行投票,即使您没有将其标记为已解决,这是令人鼓舞的