我正在尝试修改下面的查询以实现EXPECTED RESULT
,如帖子底部所示。如何修改下面的查询之一或两者以获得我想要的内容?
这只返回总反馈记录和average_rating:
版本1)
$qb = $this->createQueryBuilder('f')
->select('COUNT(f.id) AS total')
->addSelect('AVG(f.rating) AS average_rating')
->join('f.customers', 'c')
->where('c.guid = :guid')
->setParameter('guid', $guid)
->getQuery()
->execute();
版本2)
$qb = $em->createQuery(
'SELECT
COUNT(f.id) AS total,
AVG(f.ratingSeller) AS average_rating
FROM
WhateverBundle:Feedback f
JOIN
WhateverBundle:Customer c
WHERE
c.guid = :guid'
)
->setParameter('guid', $guid)
->getResult();
当前结果:
Array
(
[0] => Array
(
[total] => 11
[average_rating] => 4
)
)
反馈表
ID RATING DELIVERED CHECKED CUSTOMER_ID
1 5 Y Y 12
2 4 Y N 12
3 4 Y N 12
4 5 Y Y 12
5 2 N Y 12
CUSTOMERS TABLE
GUID NAME
12 inanzzz
预期结果:
total = 11
average_rating = 4
delivered_percentage = 80% (should take only Y in count)
checked_percentage = 60% (should take only Y in count)
答案 0 :(得分:1)
使用CASE
运算符:
版本1:
$qb = $this->createQueryBuilder('f')
->select('COUNT(f.id) AS total')
->addSelect('AVG(f.rating) AS average_rating')
->addSelect('AVG(CASE WHEN f.delivered = "Y" THEN 1 ELSE 0 END) AS delivered_percentage')
->addSelect('AVG(CASE WHEN f.checked = "Y" THEN 1 ELSE 0 END) AS checked_percentage')
->join('f.customers', 'c')
->where('c.guid = :guid')
->setParameter('guid', $guid)
->getQuery()
->execute();
第2版:
$qb = $em->createQuery(
'SELECT
COUNT(f.id) AS total,
AVG(f.ratingSeller) AS average_rating
AVG(CASE WHEN f.delivered = "Y" THEN 1 ELSE 0 END) AS delivered_percentage
AVG(CASE WHEN f.checked = "Y" THEN 1 ELSE 0 END) AS checked_percentage
FROM
WhateverBundle:Feedback f
JOIN
WhateverBundle:Customer c
WHERE
c.guid = :guid'
)
->setParameter('guid', $guid)
->getResult();
有趣的是,如果您刚刚使用适当的type="boolean"
进行实体映射,则Doctrine会将Y
和N
存储为tinyint 1
和0
,使您不必使用CASE
操作。您还可以在setter和getter函数中使用PHP true
和false
。