【问题标题】:QueryBuilder/Doctrine Select join groupbyQueryBuilder/Doctrine Select 加入 groupby
【发布时间】:2015-03-31 21:38:17
【问题描述】:

所以最近我一直在思考,但由于我缺乏对教义 2 和 symfony 查询生成器的开发,所以我还没有找到解决方案。

我有 2 张桌子: 目标:id、user_id、target_value... 储蓄:id,goal_id,amount

我需要从目标中进行选择(我表中的所有信息都来自目标表,除了我需要从每个目标的储蓄表中制作一个 SUM(金额),这样我就可以向用户展示他为自己的目标节省了多少钱)

这是 MySQL 查询:

    select 

    admin_goals.created,
    admin_goals.description,
    admin_goals.goal_date,
    admin_goals.value,
    admin_goals.budget_categ,
    sum(admin_savings.value) 

    from admin_goals 
inner join admin_savings on admin_savings.goal_id=admin_goals.id 
    where admin_goals.user_id=1 
    group by admin_goals.id

它返回我想要的,但我不知道如何用学说或查询生成器来实现它,你能告诉我一个例子吗? 我非常感谢!

【问题讨论】:

标签: php mysql symfony doctrine-orm query-builder


【解决方案1】:

我假设您只需要此字段,而不需要您的 AdminGoals 实体。在您的 AdminGoalsRepository 上,您可以执行以下操作:

public function getGoalsByUser(User $user) 
{
    $qb = $this->createQueryBuilder('goal');
    $qb->select('SUM(savings.value) AS savings_value')
       ->addSelect('goal.created')
       ->addSelect('goal.description')
       ->addSelect('goal.goalDate')
       ->addSelect('goal.value')
       ->addSelect('goal.budgetCat') //is this an entity? it will be just an ID
       ->join('goal.adminSavings', 'savings', Join::WITH))
       ->where($qb->expr()->eq('goal.user', ':user'))
       ->groupBy('goal.id')
       ->setParameter('user', $user);

    return $qb->getQuery()->getScalarResult();
}

请记住,返回对象将是一个行数组,每一行都是一个关联的数组,其中的键类似于上面的映射。

编辑

更新问题后,我将更改我建议的功能,但如果其他人希望看到不同之处,我将离开上面的示例。

首先,由于这是AdminSavingsAdminGoals 之间的单向多对一,自定义查询应该在AdminSavingsRepository 中(不像上面的)。此外,由于您需要aggregated field,这将“中断”您的一些数据获取。当您不只是渲染模板时,尽量保持尽可能多的 OOP。

public function getSavingsByUser(User $user)
{
    $qb = $this->createQueryBuilder('savings');
    //now we can use the expr() function
    $qb->select('SUM(savings.value) AS savings_value')
       ->addSelect('goal.created')
       ->addSelect('goal.description')
       ->addSelect('goal.goalDate')
       ->addSelect('goal.value')
       ->addSelect('goal.budgetCat') //this will be just an ID
       ->join('savings.goal', 'goal', Join::WITH))
       ->where($qb->expr()->eq('goal.user', ':user'))
       ->groupBy('goal.id')
       ->setParameter('user', $user);

       return $qb->getQuery()->getScalarResult();
}

奖金

public function FooAction($args) 
{
    $em = $this->getDoctrine()->getManager();
    $user = $this->getUser();
    //check if user is User etc depends on your config
    ...

    $savings = $em->getRepository('AcmeBundle:AdminSavings')->getSavingsByUser($user);

    foreach($savings as $row) {
        $savings = $row['savings_value'];
        $goalId =  $row['id'];  
        $goalCreated = $row['created'];
        [...]
    }
    [...]
}

【讨论】:

  • 我得到一个:尝试在“AppBundle\Entity\Goal”类上调用方法“createQueryBuilder”。控制器:$x=$goal->getGoalsByUser($user); // $目标=新目标(); ...在我把你的功能放在目标实体中,我做错了吗?
  • 正如我所说,这必须在您的AppBundle\Entity\GoalRepository 上。如果你没有,你可以generate它。
  • 感谢您的回答,我终于生成了我的存储库并运行了该函数.. 我得到一个:[Semantical Error] line 0, col 173 near 'savings WHERE': Error: Class AppBundle\Entity \Goal 没有名为 adminSavings 的关联 .. 这基本上意味着我在表中没有 adminsavings(这是总和)字段,但我不想为目标更改我的表结构,如果我想怎么办从其他表中显示 3-4 sums(),我是否需要为要显示的每个 sum() 创建一个表列?
  • 查看更新,savings_value 与加入时的savings 一起崩溃。此外,这里的许多名称都是我从您的查询中想到的。确保在命名实体属性时编写它们
  • 这一行我要写什么? ->join('goal.adminSavings', 'savings', Join::WITH)) ??我的目标没有 admin_savings .. 我的储蓄表中有 goal_id .. 这么多储蓄都与一个目标相关联
【解决方案2】:

如果你使用 createQuery(),那么你可以这样做:

    $dqlStr = <<<"DSQL"
select 
admin_goals.created,
admin_goals.description,
admin_goals.goal_date,
admin_goals.value,
admin_goals.budget_categ,
sum(admin_savings.value)
from admin_goals 
inner join admin_savings on admin_savings.goal_id=admin_goals.id 
where admin_goals.user_id=1 
group by admin_goals.id
DSQL;

    $em = $this->getDoctrine()->getManager();
    $query = $em->createQuery($dqlStr);
    $query->getResult();

另一方面,如果您想使用 createQueryBuilder(),可以查看此链接:http://inchoo.net/dev-talk/symfony2-dbal-querybuilder/

【讨论】:

  • 我也尝试了你的解决方案,但它不起作用,我最初收到一个 sintax 错误,没有引号?还是不需要它们?如果我加上引号,我会得到:尝试在类“Doctrine\DBAL\Connection”上调用方法“createQuery”。您的意思是调用“createQueryBuilder”吗? ....我只想运行一个简单的查询,天哪.. \
  • 我不是有意调用 createQueryBuilder()。对于复杂的查询,使用 QueryBuilder 可能会造成混乱,您可能会浪费时间。我添加了'$em = $this->getDoctrine()->getManager();'并更新!
  • 好的,我让它运行了,但我有这个错误:[Semantical Error] line 0, col 151 near 'admin_goals inner':错误:类 'admin_goals' 没有定义。 .. 似乎错误出现在 admin_goals 内部连接 ​​.. 部分
  • 这是人们编写多行字符串的一种方式:stackoverflow.com/questions/1848945/…。您可以尝试的一件事是,在我更新时不要在行前放置任何空格/制表符!
  • 这意味着你的原始 sql 查询有问题!
猜你喜欢
  • 1970-01-01
  • 2022-10-15
  • 2016-06-10
  • 2020-01-10
  • 2013-12-31
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2016-06-25
相关资源
最近更新 更多