【发布时间】: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