You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

求正确SQL/Symfony DQL语句:按唯一公司计算金额总和

解决方案:关联车辆用户所属公司的amount去重求和

问题根源

多表关联时,同一公司会因关联多个用户/车辆而重复出现在结果集中,导致SUM(amount)重复计算该公司的数值。比如用户1、2同属公司1(amount=1000),另一个公司2(amount=1000),未去重的关联会让公司1的amount被计算两次,最终得到1000*2+1000=3000,而正确结果应为1000+1000=2000。


原生SQL解决方案

方案1:子查询获取去重公司后求和(最稳妥,避免金额重复问题)

先筛选出所有关联车辆的用户所属的唯一公司ID,再基于这些ID求和公司的amount:

SELECT SUM(c.amount) AS total_amount
FROM companies c
WHERE c.id IN (
    SELECT DISTINCT uc.company_id
    FROM cars ca
    JOIN car_users cu ON ca.id = cu.car_id
    JOIN users u ON cu.user_id = u.id
    JOIN user_companies uc ON u.id = uc.user_id
);

方案2:关联后去重求和(注意:若不同公司amount相同,SUM(DISTINCT)会合并相同数值)

直接关联所有表,通过DISTINCT确保每个公司的amount只被计算一次:

SELECT SUM(DISTINCT c.amount) AS total_amount
FROM cars ca
JOIN car_users cu ON ca.id = cu.car_id
JOIN users u ON cu.user_id = u.id
JOIN user_companies uc ON u.id = uc.user_id
JOIN companies c ON uc.company_id = c.id;

Symfony DQL实现方案

假设实体映射关系如下:

  • Car与User为多对多关联(通过car_users表,Car类含$users属性)
  • User与Company为多对多关联(通过user_companies表,User类含$companies属性)

方案1:子查询去重公司后求和

$entityManager = $this->getDoctrine()->getManager();

$dql = <<<DQL
SELECT SUM(c.amount) AS totalAmount
FROM App\Entity\Company c
WHERE c.id IN (
    SELECT DISTINCT uc.id
    FROM App\Entity\Car ca
    JOIN ca.users u
    JOIN u.companies uc
)
DQL;

$query = $entityManager->createQuery($dql);
$totalAmount = $query->getSingleScalarResult();

方案2:分组公司后求和

先按公司ID分组确保每个公司唯一,再对分组后的amount求和:

$entityManager = $this->getDoctrine()->getManager();

$dql = <<<DQL
SELECT SUM(sub.amount) AS totalAmount
FROM (
    SELECT c.amount AS amount
    FROM App\Entity\Car ca
    JOIN ca.users u
    JOIN u.companies c
    GROUP BY c.id
) sub
DQL;

$query = $entityManager->createQuery($dql);
$totalAmount = $query->getSingleScalarResult();

简化写法(利用分组直接求和)

当按公司ID分组后,每个分组仅对应一个公司,此时直接对分组内的amount求和即可得到总结果:

$entityManager = $this->getDoctrine()->getManager();

$dql = <<<DQL
SELECT SUM(c.amount) AS totalAmount
FROM App\Entity\Car ca
JOIN ca.users u
JOIN u.companies c
GROUP BY c.id
DQL;

// 累加分组后的结果
$results = $query->getResult();
$totalAmount = array_reduce($results, fn($sum, $item) => $sum + $item['totalAmount'], 0);

内容的提问来源于stack exchange,提问作者Darkness007

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.23 03:23:23