【问题标题】:Doctrine QueryBuilder > Working with ManyToMany relationshipsDoctrine QueryBuilder > 处理多对多关系
【发布时间】:2017-03-29 11:08:44
【问题描述】:

我一直在为这个问题苦苦挣扎,所有相关主题都不符合我的具体需求。我正在构建一个“仪表板”,为广泛的实体提供系统监督。出于显而易见的原因,我想让我的查询尽可能少且尽可能高效。因此,我试图将我的查询限制为每个我检索所有相关信息的实体 1 个。

当我需要从多对多(或单对多)关系实体中提取特定数据时,我的问题就出现了。

例如,在以下情况下,我试图查找没有任何发票与之关联的帐户数量。

    $qb = $this->getDoctrine()->getManager()->createQueryBuilder();
    $qb->select(array(
        'COUNT(account) as totalAccounts', 
        'SUM(account.active) as activeAccounts',
        'SUM(account.approved) as approvedAccounts',
        'SUM(account.reverted) as revertedAccounts',
        'SUM(account.approvalRequested) as pendingApprovalAccounts',
        "SUM(CASE WHEN COUNT(account.invoices) = 0 THEN 1 ELSE 0 END) as testAccounts"
    ))
    ->from('AppBundle:Account', 'account');

我收到以下错误: QueryException: [Semantical Error] line 0, col 252 near 'invoices) = 0': Error: Invalid PathExpression。需要 StateFieldPathExpression 或 SingleValuedAssociationField。

在下面的示例中,我试图找出附有未付发票的用户数量。我通过加入 user.invoices 尝试了不同的方法。

    $qb = $this->getDoctrine()->getManager()->createQueryBuilder();
    $qb->select(array(
        'COUNT(user) as totalUsers', 
        'SUM(user.active) as activeUsers',
        "SUM(CASE WHEN user.userType = 'MONTHLY' AND user.active = true THEN 1 ELSE 0 END) as monthlyUsers",
        "SUM(CASE WHEN user.userType = 'PAYG' AND user.active = true THEN 1 ELSE 0 END) as paygUsers",
        "SUM(CASE WHEN user.noticeType = 'SWITCH' AND user.active = true THEN 1 ELSE 0 END) as noticeUsersPayg",
        "SUM(CASE WHEN user.noticeType = 'DISABLE' AND user.active = true THEN 1 ELSE 0 END) as noticeUsersDisable",
        "SUM(CASE WHEN SUM(CASE WHEN invoices.datePaid is null THEN 1 ELSE 0 END) > 0 THEN 1 ELSE 0 END) as suspendedUsers",
    ))
    ->from('AppBundle:User', 'user')
    ->leftJoin('user.invoices', 'invoices');

在这种情况下,我收到错误: SQLSTATE[HY000]:一般错误:1111 无效使用组函数

我可以使用 SQL 中所有必要的 SELECT 子查询轻松构建正确的查询,但我正在尝试通过使用 QueryBuilder 以正确的方式执行此操作。 QueryBuilder 似乎也不接受或允许 SELECT 子查询。我知道我可能做错了一些(或很多)事情,这就是我发布这个问题的原因。我认为如果这个问题得到正确回答,其他人会受益匪浅,因为关系实体影响返回数据的查询是我们都遇到过的问题,我找不到任何合适的内容来解决这个问题。

【问题讨论】:

  • 我看不到您在哪里指定要分组的列。
  • @SloanThrasher 我没有指定任何要分组的列。除非我弄错了,否则没有必要。在普通 SQL 中(就第二个示例而言)我会有 SELECT ...., SUM(CASE WHEN (SELECT COUNT(id) FROM invoices WHERE datePaid is null AND id in (SELECT invoice_id from invoice_users iu where iu.user_id = user.id)) > 0 THEN 1 ELSE 0 END) as suspendedUsers from users user 不需要 group by
  • 您收到的错误消息表明并非如此。您正在使用分组函数,因此您需要告诉它应该在哪些列上对数据进行分组以进行求和、计数等。
  • @SloanThrasher 添加$qb->groupBy(user.id);$qb->groupBy('invoices');$qb->groupBy('invoices.id'); 给出相同的组函数错误。添加 $qb->groupBy(user.invoices);$qb->groupBy('invoices.users'); 会产生 Invalid PathExpression 错误,如第一个示例所示。我真的不知道我还能按什么分组。
  • 我不熟悉您用于构造查询的库,但 ->leftJoin('user.invoices', 'invoices'); 应该是 ->leftJoin('user.invoices', 'invoices.id'); 或者类似的东西?在常规 sql 语法中,您将在 JOIN 子句的 ON 部分中为关系的双方指定表和列。

标签: php mysql entity-framework symfony doctrine-orm


【解决方案1】:

您现在主要与 ORM 作斗争,我认为这是您最好使用本机查询的情况之一。您基本上只返回用于报告的标量值,使用 ORM 并没有太多优势。

http://docs.doctrine-project.org/projects/doctrine-orm/en/latest/reference/native-sql.html

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多