内部加入多对多关系
Inner join on many to many relation
我的 symfony 项目中有这两个实体:房屋和软件。
很多家可以有很多软件并且很多软件可以属于很多家
我试图只获取 家庭 ,假设 软件 n° 1 + 软件 n°2。
实际上,我已经设法检索到 具有软件 n°1 和软件 n°2 的 Home,但没有同时具有 soft 1 + soft2
如果我没记错的话应该是Inner join join吧?
这是我的实体和存储库的方法:
class Software {
/**
* @ORM\ManyToMany(targetEntity="App\Entity\Home", mappedBy="softwares")
*/
private $homes;
public function __constuct() {
$this->homes = new ArrayCollection();
}
// ...
public function getHomes(){ ... }
public function addHome(Home $home){ ... }
// ...
}
class Home {
/**
* @ORM\ManyToMany(targetEntity="App\Entity\Software", inversedBy="homes")
*/
private $softwares;
public function __constuct() {
$this->softwares = new ArrayCollection();
}
//...
public function getSoftwares(){ ... }
public function addSoftware(Software $software){ ... }
//...
}
主存储库
class HomeRepository extends ServiceEntityRepository {
public function innerJoinSoftware($softIds)
{
$qb = $this->createQueryBuilder('c')
->innerJoin('c.softwares', 's')
->andWhere('s.id IN(:softIds)')
->setParameter('softIds', $softIds)
;
return $qb->getQuery()->getResult();
}
}
为了说明我的观点:
Home1有soft1,soft2
Home2有soft1,soft3
Home3有soft2,soft3
我想做的是
dump(homeRepo->innerJoinSoftware([1, 2]));
//should output Home1 but actually I have
//it outputs Home1, Home2, Home3
这是我提出的 SQL 版本,但我仍然无法使用 Doctrine
SELECT home.id, home.name FROM Home as home
INNER JOIN (
SELECT home_id as home_id, COUNT(home_id) as count_home
FROM home_software
WHERE software_id IN (1, 2)
GROUP BY home_id
HAVING count_home = 2) as soft # count_home should be dynamic
ON home.id = soft.home_id
ORDER BY home.name
这是我解决这个问题的方法(在我发布的原始 SQL 的帮助下)
public function findBySoftwaresIn($softIds)
{
//retrieve nbr of soft per home
$nbrSoftToFind = count($softIds);
$qb = $this->createQueryBuilder('h');
$qb->innerJoin('h.softwares', 's')
->andWhere('h.id IN (:softIds)')
->setParameter('softIds', $softIds)
//looking for home coming back by nbrSoft
->andHaving($qb->expr()->eq($qb->expr()->count('h.id'), $nbrSoftToFind))
->groupBy('h.id')//dont forget to group by ID
->addOrderBy('h.name')
;
return $qb->getQuery()->getResult();
}
我的 symfony 项目中有这两个实体:房屋和软件。
很多家可以有很多软件并且很多软件可以属于很多家
我试图只获取 家庭 ,假设 软件 n° 1 + 软件 n°2。
实际上,我已经设法检索到 具有软件 n°1 和软件 n°2 的 Home,但没有同时具有 soft 1 + soft2
如果我没记错的话应该是Inner join join吧?
这是我的实体和存储库的方法:
class Software {
/**
* @ORM\ManyToMany(targetEntity="App\Entity\Home", mappedBy="softwares")
*/
private $homes;
public function __constuct() {
$this->homes = new ArrayCollection();
}
// ...
public function getHomes(){ ... }
public function addHome(Home $home){ ... }
// ...
}
class Home {
/**
* @ORM\ManyToMany(targetEntity="App\Entity\Software", inversedBy="homes")
*/
private $softwares;
public function __constuct() {
$this->softwares = new ArrayCollection();
}
//...
public function getSoftwares(){ ... }
public function addSoftware(Software $software){ ... }
//...
}
主存储库
class HomeRepository extends ServiceEntityRepository {
public function innerJoinSoftware($softIds)
{
$qb = $this->createQueryBuilder('c')
->innerJoin('c.softwares', 's')
->andWhere('s.id IN(:softIds)')
->setParameter('softIds', $softIds)
;
return $qb->getQuery()->getResult();
}
}
为了说明我的观点:
Home1有soft1,soft2
Home2有soft1,soft3
Home3有soft2,soft3
我想做的是
dump(homeRepo->innerJoinSoftware([1, 2]));
//should output Home1 but actually I have
//it outputs Home1, Home2, Home3
这是我提出的 SQL 版本,但我仍然无法使用 Doctrine
SELECT home.id, home.name FROM Home as home
INNER JOIN (
SELECT home_id as home_id, COUNT(home_id) as count_home
FROM home_software
WHERE software_id IN (1, 2)
GROUP BY home_id
HAVING count_home = 2) as soft # count_home should be dynamic
ON home.id = soft.home_id
ORDER BY home.name
这是我解决这个问题的方法(在我发布的原始 SQL 的帮助下)
public function findBySoftwaresIn($softIds)
{
//retrieve nbr of soft per home
$nbrSoftToFind = count($softIds);
$qb = $this->createQueryBuilder('h');
$qb->innerJoin('h.softwares', 's')
->andWhere('h.id IN (:softIds)')
->setParameter('softIds', $softIds)
//looking for home coming back by nbrSoft
->andHaving($qb->expr()->eq($qb->expr()->count('h.id'), $nbrSoftToFind))
->groupBy('h.id')//dont forget to group by ID
->addOrderBy('h.name')
;
return $qb->getQuery()->getResult();
}