使用不同where子句的average()和百分比计算

时间:2014-11-28 15:50:02

标签: symfony doctrine-orm dql

我正在尝试修改下面的查询以实现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)

1 个答案:

答案 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会将YN存储为tinyint 10 ,使您不必使用CASE操作。您还可以在setter和getter函数中使用PHP truefalse