Php 条令独立计数

Php 条令独立计数,php,mysql,symfony,doctrine-orm,doctrine,Php,Mysql,Symfony,Doctrine Orm,Doctrine,检索实体集合上的不同计数的最佳做法是什么 在这个示例实体(Customer)中,我与Orders有oneToMany关系 我想计算客户订购了多少销售和产品: > select * from orders; +----------+----------+----------+ | customer | sale_ref | prod_ref | +----------+----------+----------+ | 1 | sale_1 | prod_1 | | 1

检索实体集合上的
不同计数
的最佳做法是什么

在这个示例实体(
Customer
)中,我与
Orders
oneToMany
关系

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

> 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;

    /**
     * Unique product reference
     * @var string $productRef
     * @ORM\Column(name="product_ref", type="string")
     */
    protected $productRef;

    /**
     * @return Customer
     */
    public function getCustomer(): Customer
    {
        return $this->customer;
    }

    /**
     * @return string
     */
    public function getProductRef(): string
    {
        return $this->productRef;
    }

    /**
     * @return string
     */
    public function getSalesRef(): string
    {
        return $this->salesRef;
    }

}
使用
Customer->getOrdersProductCount()
可以很好地检索产品计数,这被称为“良好做法”,因为它不会在集合完全加载时影响数据库:

如果将关联标记为额外延迟,则可以调用集合上的以下方法,而无需触发集合的满载
collection\count()

但是,在此示例中,
客户
可以有多个产品进行销售-其中
saleref
是非唯一的。检索
salesRef
不同计数的最佳方法是什么

这可以/应该在实体存储库类中处理:

class OrdersRepository
{

    public function getSalesCount($customer): int
    {
        return (int)$this->createQueryBuilder('o')
            ->select('COUNT(DISTINCT(o.salesRef))')
            ->where('o.customer = :customer')
            ->setParameter('customer', $customer)
            ->setMaxResults(1)
            ->getQuery()
            ->getSingleScalarResult();
    }

    public function getProductCount($customer): int
    {
        return (int)$this->createQueryBuilder('o')
            ->select('COUNT(o.productRef)')
            ->where('o.customer = :customer')
            ->setParameter('customer', $customer)
            ->setMaxResults(1)
            ->getQuery()
            ->getSingleScalarResult();
    }

}
这是可行的,但我需要加载entityManager/CustomerRepository才能访问这些方法,而至少我可以从实体中检索产品计数

如何从客户实体内部访问不同的销售计数(如果有的话)


我考虑过使用该方法和/或循环通过
订单
实体创建一个数组,其中
salesRef
作为键,然后使用,但这似乎不“正确”-我怀疑我知道答案(使用实体存储库)但我更希望能够从
客户
实体中访问销售计数-最佳做法/方法是什么?

我认为这应该做到,而且是一种更方便的方式。但是我没有测试它

    $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();
参考资料如下:


希望这有帮助

这可以通过多种方式实现,因此有很多答案。从简单但昂贵的(
count($user->getOrders())
)到复杂而高效的(编写原始sql)以及介于两者之间的一切。这完全取决于你在寻找什么。对于你的情况,我认为使用过滤器或数组_unique是更好的方法。因为这不会影响另一个数据库查询。而且您不能在EntityThank中使用repository-我正在寻找一种有效的方法,在不加载EntityManager/repository的情况下从客户实体检索不同的销售计数。。。这是一个漫长的过程,因为我怀疑我将不得不加载em/存储库来高效/经济地检索它,但我只是想知道它是否可能从实体内部进行only@JessGabriel是的,这就是我要去的地方,但在继续之前,我想就解决这个问题的最佳方法征求意见。了解EM/Repo在实际实体中不可用/不推荐,它似乎只需要执行一个DB查询来检索所有记录,然后客户实体就可以进行筛选…我也会这样做(或类似),但我认为单标量结果不需要
->setMaxResults(1)
。谢谢-是的,这非常有效,但我正在考虑的是,我是否可以经济地从客户实体中检索订单销售参考的不同计数(无需加载实体管理器/存储库)-不确定这是否推荐/可能-简而言之-否。这是最好的方法。换句话说,如果你真的不想在你的控制器功能中使用repo(我看不出有什么原因,这就是它们的使用方式),你可以“打破”MVC结构,在它的位置编写原始sql。