0

我的问题是带有 Order By 的 Doctrine 和 SQL GroupBy

所以稍微描述一下,有一个shop(s),这个shop有article(a),还有一个实体访问counter(vc),用来统计不同事物的访问量,也用于shop和article。

我想要一个文章列表(热门文章),但只是每个商店访问量最大的文章。

   class Shop {
       private $id;
       private $name;
       private $is_published;
       ...
       /**
        * OneToMany articles
        */
       private $articles; 
   }

   class Article {
       private $id;
       private $name;
       private $is_published;
       ...
       /* ManyToOne Shop*/
       private $shop;
   }

   class VisitCounter {
       private $id;
       private $object_type; //0 for Article, 1 for Shop, 2 for Category
       private $object_id;
       ...
       private $nr_alltime_visits;
   }

然后我在文章存储库中尝试了以下查询:

    $query = $this->createQueryBuilder('a', 's', 'vc')
            ->select('a, s')
            ->leftJoin('a.shop', 's')
            ->leftJoin('ProjMyBundle:VisitCounter', 'vc', 'WITH', 'vc.object_type = 0 AND cs.object_id= a.id')
            ->where('a.is_published = 1 AND s.is_published = 1)
            ->orderBy('vc.nr_alltime_visits', 'DESC')
            ->groupBy('a.shop');

但是因为我没有得到预期的文章,如果我删除该组,我会得到正确的文章,但每个商店超过 1 个。

有任何想法吗?

在这个问题之前,我在商店和文章中有一个字段(私人 $nr_visits),然后我有这样的东西(将来可以帮助某人):

    $query = $this->createQueryBuilder('a', 's')
                  ->select('a, s')
                  ->where('a.is_published = 1 AND s.is_published = 1')
                  ->leftJoin('a.shop', 's')
                  ->groupBy('a.shop')
                  ->orderBy('nr_visits', 'DESC');


    $query->andWhere('a.nr_visits = (SELECT MAX(a2.nr_visits) as nr_visits2 FROM ProjMyBundle:Article AS a2 WHERE a2.is_published = 1 AND a2.shop=a.shop GROUP BY a2.shop)');
4

2 回答 2

0

VisitCounter 与 Shop 或 Article 没有直接关系,因为 object_id 列依赖于 object_type 列。因此,您不能使用学说的 fetch-joins,因为它希望存在直接关系。您必须编写一些本机 SQL,但您仍然可以使用一些教义好东西来帮助您制作漂亮的对象(尽管数组更适合读取操作)。

至于您的查询,您需要查找每个数据库平台上不同的“Top N by group”(您没有在问题中指定)。您必须按文章(和商店)分组,然后对您聚合的行执行 COUNT(*)。

在这里您可以阅读如何从本地 sql 映射结果:http: //docs.doctrine-project.org/en/latest/reference/native-sql.html#examples

于 2013-08-04T19:53:29.773 回答
0

可以使用像旧版本中的子查询:

$qb->select('a, s, cs')->leftJoin('a.shop', 's')
        ->leftJoin('ProjMyBundle:VisitCounter', 'vc', 'WITH', 'vc.object_type = :object_type AND cs.object_id=a.id')
        ->where('a.published = 1 AND s.published = 1)
        ->andWhere('vc. nr_alltime_visits = (SELECT MAX(vc2.nr_alltime_visits) as hits2 FROM ProjMyBundle:Article AS a2
                            LEFT JOIN ProjMyBundle:VisitCounter AS vc2 WITH vc2.object_type = :object_type AND vc2.object_id = a2.id
                            WHERE a2.published = 1 v2.shop=v.shop GROUP BY v2.shop)')
        ->setParameters(array('object_type' => Clicks::$TYPE_ARTICLE))
        ->orderBy('cs.nr_alltime_visits', 'DESC')
        ->groupBy('v.shop')->getQuery()->getResult();
于 2013-08-24T20:38:34.003 回答