Php 原则DQL-WHERE子句中的嵌套子查询抛出语法错误
我试图根据两个关联表的汇总和合并结果从一个表中查询数据。 当作为本机SQL执行时,查询工作正常,不幸的是,我的应用程序仅限于在QueryBuilder对象上使用Doctrine的DQL 以下是我构建QueryBuilder的方式: $resUnitQuery=$queryBuilder->getEntityManager->createQueryBuilder; $resUnitQuery->选择“COALESCESUMpc.residentialUnits,0” ->fromPropertyConnection::类“pc” ->其中$rootAlias.id=pc.contract; $comUnitQuery=$queryBuilder->getEntityManager->createQueryBuilder; $comUnitQuery->选择“COALESCESUMpwa.residential\u units,0” ->fromPropertyWithoutAddress::类“pwa” ->其中$rootAlias.id=pwa.contract; $queryBuilder=$this->getEntityManagerContract::class->createQueryBuilder; $queryBuilder ->选择“id” ->fromContract::类“o” ->在哪里Php 原则DQL-WHERE子句中的嵌套子查询抛出语法错误,php,sql-server,symfony,doctrine,Php,Sql Server,Symfony,Doctrine,我试图根据两个关联表的汇总和合并结果从一个表中查询数据。 当作为本机SQL执行时,查询工作正常,不幸的是,我的应用程序仅限于在QueryBuilder对象上使用Doctrine的DQL 以下是我构建QueryBuilder的方式: $resUnitQuery=$queryBuilder->getEntityManager->createQueryBuilder; $resUnitQuery->选择“COALESCESUMpc.residentialUnits,0” ->fromPropertyC
“:residentialUnits正确,DBAL不支持对子查询进行算术运算。另外,DBAL不支持联接子查询,请从中联接选择。。。在不使用本机查询的情况下打开 另一个问题是子查询的WHERE语句依赖于根查询,将导致根查询执行完整表扫描。每行执行每个子查询,除非向根查询添加了条件,其中o.id 由于子查询和值取决于根查询id。您可以重写查询,将子查询用作隐藏列和HAVING子句,从添加的列结果中筛选id结果集
$em = $queryBuilder->getEntityManager();
$expr = $em->getExpressionBuilder();
$qbPC = $em->createQueryBuilder()
->select('COALESCE(SUM(pc.residentialUnits), 0)')
->from(App\Entity\PropertyConnection::class, 'pc')
->where($expr->eq('pc.contract', "$rootAlias.id"));
$qbPWA = $em->createQueryBuilder()
->select('COALESCE(SUM(pwa.residential_units), 0)')
->from(App\Entity\PropertyWithoutAddress::class, 'pwa')
->where($expr->eq('pwa.contract', "$rootAlias.id"));
$qb = $this->getEntityManager(Contract::class)
->createQueryBuilder()
->select('o.id')
->from(App\Entity\Contract::class, 'o')
->addSelect('(' . $qbPC->getDQL() . ') AS HIDDEN pc_ru')
->addSelect('(' . $qbPWA->getDQL() . ') AS HIDDEN pwa_ru')
->having($expr->lte(':v', 'pc_ru + pwa_ru'))
->setParameter('v', $params['rangeFrom']);
dump($qb->getDQL());
结果DQL
SELECT
o.id,
(SELECT
COALESCE(SUM(pc.residentialUnits), 0)
FROM App\Entity\PropertyConnection pc
WHERE pc.contract = o.id
) AS HIDDEN pc_ru,
(SELECT
COALESCE(SUM(pwa.residential_units), 0)
FROM App\Entity\PropertyWithoutAddress pwa
WHERE pwa.contract = o.id
) AS HIDDEN pwa_ru
FROM App\Entity\Contract o
HAVING :v <= pc_ru + pwa_ru
正确,DBAL不支持对子查询进行算术运算。另外,DBAL不支持联接子查询,请从中联接选择。。。在不使用本机查询的情况下打开 另一个问题是子查询的WHERE语句依赖于根查询,将导致根查询执行完整表扫描。每行执行每个子查询,除非向根查询添加了条件,其中o.id 由于子查询和值取决于根查询id。您可以重写查询,将子查询用作隐藏列和HAVING子句,从添加的列结果中筛选id结果集
$em = $queryBuilder->getEntityManager();
$expr = $em->getExpressionBuilder();
$qbPC = $em->createQueryBuilder()
->select('COALESCE(SUM(pc.residentialUnits), 0)')
->from(App\Entity\PropertyConnection::class, 'pc')
->where($expr->eq('pc.contract', "$rootAlias.id"));
$qbPWA = $em->createQueryBuilder()
->select('COALESCE(SUM(pwa.residential_units), 0)')
->from(App\Entity\PropertyWithoutAddress::class, 'pwa')
->where($expr->eq('pwa.contract', "$rootAlias.id"));
$qb = $this->getEntityManager(Contract::class)
->createQueryBuilder()
->select('o.id')
->from(App\Entity\Contract::class, 'o')
->addSelect('(' . $qbPC->getDQL() . ') AS HIDDEN pc_ru')
->addSelect('(' . $qbPWA->getDQL() . ') AS HIDDEN pwa_ru')
->having($expr->lte(':v', 'pc_ru + pwa_ru'))
->setParameter('v', $params['rangeFrom']);
dump($qb->getDQL());
结果DQL
SELECT
o.id,
(SELECT
COALESCE(SUM(pc.residentialUnits), 0)
FROM App\Entity\PropertyConnection pc
WHERE pc.contract = o.id
) AS HIDDEN pc_ru,
(SELECT
COALESCE(SUM(pwa.residential_units), 0)
FROM App\Entity\PropertyWithoutAddress pwa
WHERE pwa.contract = o.id
) AS HIDDEN pwa_ru
FROM App\Entity\Contract o
HAVING :v <= pc_ru + pwa_ru
谢谢你的快速回复。Doctrine现在似乎能够解析它,不幸的是,我的数据库不知道我们在子查询中定义的两个隐藏别名:SQL错误[207][S0001]:无效列名“sclr_46”。sclr_46是作为第一个子查询的别名生成的变量。如果有帮助的话,我使用的是SQLServer。@Renetharsis不幸的是,MSSQL不像其他RDBMS那样在HAVING子句中支持聚合列别名,而且ORM还没有构建来解析复杂的查询。要解决此问题,您需要在发出合同查询之前使用本机查询或过滤ID。有关此问题的详细信息,请参见:这很遗憾。那我就得解决这个问题了。非常感谢你的支持。由于您的答复对其他DBMS有效,我将其标记为已解决!谢谢你的快速回复。Doctrine现在似乎能够解析它,不幸的是,我的数据库不知道我们在子查询中定义的两个隐藏别名:SQL错误[207][S0001]:无效列名“sclr_46”。sclr_46是作为第一个子查询的别名生成的变量。如果有帮助的话,我使用的是SQLServer。@Renetharsis不幸的是,MSSQL不像其他RDBMS那样在HAVING子句中支持聚合列别名,而且ORM还没有构建来解析复杂的查询。要解决此问题,您需要在发出合同查询之前使用本机查询或过滤ID。有关此问题的详细信息,请参见:这很遗憾。那我就得解决这个问题了。非常感谢你的支持。由于您的答复对其他DBMS有效,我将其标记为已解决!