我有以下查询:
SELECT COUNT(a0_.id) AS sclr0, LOWER(a0_.city) AS sclr1
FROM address a0_
INNER JOIN customer c1_ ON (c1_.customer_address = a0_.id)
WHERE a0_.city IS NOT NULL
AND a0_.city <> ''
AND (
c1_.id IN (
SELECT p2_.customer AS sclr2
FROM payment p2_
WHERE p2_.init <> 1
AND p2_.unpaid <> 1
AND p2_.cancel_date IS NULL
AND (p2_.value > 0 OR p2_.date BETWEEN '2011-03-23 00:00:00' AND '2011-03-23 23:59:59')
AND p2_.customer IS NOT NULL
GROUP BY p2_.customer
)
) GROUP BY sclr1
LIMIT 5
我使用以下DQL构建:
$qb = $this->createQueryBuilder('a')
->select('COUNT(a) AS total, LOWER(a.city) AS city')
->join('EvoUserBundle:Customer', 'c', 'WITH', 'c.customerAddress = a')
->where('a.city IS NOT NULL')
->andWhere('a.city != \'\'')
->groupBy('city')
->setMaxResults(5);
$subquery = $this->em->getRepository('EvoSaleBundle:Payment')->createQueryBuilder('p')
->select('IDENTITY(p.customer)')
->andWhere('p.init != 1')
->andWhere('p.unpaid != 1')
->andWhere('p.cancelDate IS NULL')
->andWhere('p.value > 0 OR p.date BETWEEN \'2011-03-23 00:00:00\' AND \'2011-03-23 23:59:59\'')
->andWhere('p.customer IS NOT NULL')
->groupBy('p.customer');
$qb->andWhere($qb->expr()->in('c', $subquery->getDQL()));
并返回以下数据集:
array(10) {
[0]=>
array(2) {
["total"]=>
string(1) "3"
["city"]=>
string(18) "epinay sur seine"
}
[1]=>
array(2) {
["total"]=>
string(1) "7"
["city"]=>
string(8) "firfol"
}
[2]=>
array(2) {
["total"]=>
string(1) "2"
["city"]=>
string(20) "fontenay sous bois"
}
[3]=>
array(2) {
["total"]=>
string(1) "1"
["city"]=>
string(13) "puyravault"
}
[4]=>
array(2) {
["total"]=>
string(1) "3"
["city"]=>
string(8) "torcy"
}
}
向查询添加ORDER BY子句时出现问题:
SELECT COUNT(a0_.id) AS sclr0, LOWER(a0_.city) AS sclr1
FROM address a0_
INNER JOIN customer c1_ ON (c1_.customer_address = a0_.id)
WHERE a0_.city IS NOT NULL
AND a0_.city <> ''
AND (
c1_.id IN (
SELECT p2_.customer AS sclr2
FROM payment p2_
WHERE p2_.init <> 1
AND p2_.unpaid <> 1
AND p2_.cancel_date IS NULL
AND (p2_.value > 0 OR p2_.date BETWEEN '2011-03-23 00:00:00' AND '2011-03-23 23:59:59')
AND p2_.customer IS NOT NULL
GROUP BY p2_.customer
)
) GROUP BY sclr1
ORDER BY sclr0 DESC
LIMIT 5
这使得查询执行永远持续(超过2分钟,不得不杀死MySQL进程)。经过一些研究,我发现了this answer类似的问题,它解决了我在纯SQL中的问题。但我无法在DQL中重现它。我试过了:
$qb2 = $this->em->createQueryBuilder()
->select('sclr0, sclr1')
->from('('.$qb->getDQL().')', 't')
->orderBy('sclr0', 'DESC')
->setMaxResults(5);
产生以下DQL:
SELECT sclr0, sclr1 FROM (
SELECT COUNT(a) AS total, LOWER(a.city) AS city
FROM Evo\UserBundle\Entity\Address a
INNER JOIN EvoUserBundle:Customer c WITH c.customerAddress = a
WHERE a.city IS NOT NULL
AND a.city != ''
AND (
c IN(
SELECT IDENTITY(p.customer)
FROM Evo\SaleBundle\Entity\Payment p
WHERE p.init != 1
AND p.unpaid != 1
AND p.cancelDate IS NULL
AND (p.value > 0 OR p.date BETWEEN '2011-03-23 00:00:00' AND '2011-03-23 23:59:59')
AND p.customer IS NOT NULL
GROUP BY p.customer
)
) GROUP BY city
) t ORDER BY sclr0 DESC
返回以下错误:
[Semantical Error] line 0, col 25 near '(SELECT COUNT(a)': Error: Class '(' is not defined
。我看过Doctrine2 doesn't support FROM subqueries because it wouldn't be able to build a result set mapping.
但我有特定的理由在DQL中构建此查询,我不能使用SQL。任何提示/解决方法,使其工作?
答案 0 :(得分:0)
使用ResultSetMappingBuilder
创建您的特定SQL并将其映射到实体
https://www.doctrine-project.org/projects/doctrine-orm/en/2.7/reference/native-sql.html