将带子查询的SQL转换为Doctrine Query Builder

时间:2018-06-04 14:32:44

标签: php doctrine-orm query-builder

我遵循数据库结构:


List item

trips (ManyToMany to tags over table trips_tags)
+----+----------------+
| id |      name      |
+----+----------------+
|  1 | Czech Republic |
|  2 | Germany        |
|  3 | Poland         |
+----+----------------+

tags
+----+-----------+
| id |   name    |
+----+-----------+
|  1 | Mountains |
|  2 | Beach     |
|  3 | City      |
+----+-----------+

trips_tags
+----------+---------+
| trips_id | tags_id |
+----------+---------+
|        1 |       1 |
|        1 |       2 |
|        3 |       1 |
+----------+---------+

我需要选择包含我指定的所有标签的行程。

  • 需要旅行标签山脉作为海滩我只得到捷克共和国。
  • 只需要标记山脉,捷克共和国和波兰

我写了一个简单的SQL

SELECT trip.name, trip.id
FROM trips AS trip
WHERE (
    SELECT COUNT(trip_tag.tags_id) 
    FROM trips_tags AS trip_tag 
    WHERE trip_tag.tags_id IN (1, 2) 
      AND trip_tag.trips_id = trip.id
) = numberOfTags`

现在我在DQL中编写此SQL有问题。有人可以帮忙吗?

谢谢

1 个答案:

答案 0 :(得分:1)

看起来你在旅行和标签之间有很多很多的关系,最好采用教条的方式来定义你的情节并将它们与许多人联系起来,如

class Trip
{
    // ...

    /**
     * @ManyToMany(targetEntity="Tag", inversedBy="trips")
     * @JoinTable(name="trip_tag")
     */
    private $tags;

    public function __construct() {
        $this->tag s= new \Doctrine\Common\Collections\ArrayCollection();
    }

    // ...
}

/** @Entity */
class Tag
{
    // ...
    /**
     * @ManyToMany(targetEntity="Trip", mappedBy="tags")
     */
    private $trips;

    public function __construct() {
        $this->trips = new \Doctrine\Common\Collections\ArrayCollection();
    }

    // ...
}

然后使用一些聚合构建您的DQL

$tagIds = [1,2];
$qb = $this->createQueryBuilder('trip');
$qb ->addSelect('COUNT(tags.id) AS total_tags')
    ->leftJoin('trip.tags', 'tags')
    ->add('where', $qb->expr()->in('tags', $tagIds))
    ->groupBy('trip.id')
    ->having('total_tags = @numberOfTags')
    ->getQuery()
    ->getResult();

Many-To-Many, Bidirectional

Doctrine2 get object without relations

Symfony2 - Doctrine2 QueryBuilder WHERE IN ManyToMany field