猿问

学说区别计数

检索实体集合的最佳做法是什么DISTINCT COUNT?


在此示例实体 ( Customer) 中,我oneToMany与 有关系Orders。


我想计算客户订购了多少销售额和产品:


> select * from orders;

+----------+----------+----------+

| customer | sale_ref | prod_ref |

+----------+----------+----------+

| 1        | sale_1   | prod_1   |

| 1        | sale_1   | prod_2   |

| 1        | sale_2   | prod_1   |

| 1        | sale_3   | prod_3   |

+----------+----------+----------+


> select count(prod_ref) from order where customer = 1;

+-----------------+

| count(prod_ref) |

+-----------------+

| 4               |

+-----------------+



> select count(distinct(sale_ref)) from order where customer = 1;

+-----------------+

| count(prod_ref) |

+-----------------+

| 3               |

+-----------------+

这是代码


use Doctrine\ORM\Mapping as ORM;


class Customer

{


    /**

     * @var \Doctrine\Common\Collections\Collection

     * @ORM\OneToMany(targetEntity="Orders", mappedBy="customer", cascade={"persist", "remove"}, fetch="EXTRA_LAZY")

     */

    protected $orders;


    /**

     * @return \Doctrine\Common\Collections\Collection

     */

    public function getOrders(): \Doctrine\Common\Collections\Collection

    {

        return $this->orders;

    }


    /**

     * @return int

     */

    public function getOrdersProductCount(): int

    {

        return $this->orders->count();

    }


}


class Orders

{


    /**

     * @var Customer $customer

     * @ORM\ManyToOne(targetEntity="Customer", inversedBy="orders")

     */

    protected $customer;


    /**

     * Non-unique sales reference

     * @var string $salesRef

     * @ORM\Column(name="sales_ref", type="string")

     */

    protected $salesRef;

使用该Customer->getOrdersProductCount()作品非常适合检索产品数量,据说是“良好做法”,因为它不会在完全加载集合时访问数据库:


https://www.doctrine-project.org/projects/doctrine-orm/en/2.7/tutorials/extra-lazy-associations.html


如果您将关联标记为额外惰性,则可以在不触发集合的完整加载的情况下调用集合的以下方法Collection#count()


但是,在此示例中,aCustomer可以有多个产品用于销售 - 其中salesRef是非唯一的。DISTINCT COUNT检索的最佳方法是什么salesRef?


泛舟湖上清波郎朗
浏览 160回答 1
1回答

喵喵时光机

我认为这应该做到,并且是一种更便携的方式。我没有测试它。    $qb = $this->createQueryBuilder('o');    return (int)$qb        ->select($qb->expr()->countDistinct('o.salesRef'))        ->where('o.customer = :customer')        ->setParameter('o.customer', $customer)        ->setMaxResults(1)        ->getQuery()        ->getSingleScalarResult();
随时随地看视频慕课网APP
我要回答