symfony2 - Doctrine - 如何使用count和group by进行多重选择

时间:2013-09-24 21:13:07

标签: sql symfony doctrine-orm

在Symfony2和Doctrine中,我想执行一个返回count和group by的查询。

这是我尝试过的。这是我想要运行的SQL:

SELECT   `terrain_id` , COUNT( * ) 
FROM     `Partie` 
WHERE     1 =1
GROUP BY `terrain_id`

使用我的实体:

class Partie
{   
    /**
     * @var integer
     *
     * @ORM\Column(name="id", type="integer")
     * @ORM\Id
     * @ORM\GeneratedValue(strategy="AUTO")
     */
    private $id;

    /**
     * @ORM\ManyToOne(targetEntity="Gp\UserBundle\Entity\User", 
        inversedBy="parties",         cascade={"persist"})
     * @ORM\JoinColumn(nullable=false)
     */
    private $user;

    /**
     * @ORM\ManyToOne(targetEntity="Gp\JeuxBundle\Entity\Terrain")
     */
    private $terrain;

这是我的PartieRepository

public function getTest(\Gp\UserBundle\Entity\User $user){
    return $this->createQueryBuilder('p')
    ->select('count(p), p.terrain')
    ->where('p.user = :user')
    ->setParameter('user', $user)
    ->groupBy('r.terrain')
    ->getQuery()
    ->getResult();
}

这是我得到的错误:

[Semantical Error] line 0, col 19 near 'terrain FROM': Error: 
Invalid PathExpression.   Must be a StateFieldPathExpression.

3 个答案:

答案 0 :(得分:4)

您可能希望使用Native Query

$sql = "SELECT terrain_id as terrain,
                count(*) AS count "
            ."FROM Partie "
            ."GROUP BY terrain_id;";


$rsm = new ResultSetMapping;
$rsm->addScalarResult('terrain', 'terrain');
$rsm->addScalarResult('count', 'count');
$query = $this->_em->createNativeQuery($sql, $rsm);
return $query->getResult();

根据需要添加任何having / where子句。

以下是我的结果:

Array
(
    [0] => Array
        (
            [terrain] => 
            [count] => 7
        )

    [1] => Array
        (
            [terrain] => 1
            [count] => 5
        )

    [2] => Array
        (
            [terrain] => 2
            [count] => 1
        )

)

第一个数组中缺少terrain是由于terrain_id为空。

修改

OP有意想不到的结果,所以这里有一些故障排除步骤:

1)在var_dump($query->getSQL());语句之前尝试return,然后直接针对您的数据库运行SQL。如果这会产生不正确的结果,请检查查询并根据需要更改$sql

2)如果#1产生了正确的结果,请在返回语句之前尝试var_dump($query->getResult()); 。如果这会产生正确的结果,那么代码中的某些内容会更深入。是时候查看为什么terrain被过滤了。它可能就像在SQL和addScalarResult中删除或更改别名一样简单。

3)尝试更简单的功能:

    $sql = "SELECT distinct(terrain_id) FROM Partie;";

    $rsm = new ResultSetMapping;
    $rsm->addScalarResult('terrain_id', 'terrain_id');
    $query = $this->_em->createNativeQuery($sql, $rsm);
    var_dump($query->getSQL());
    var_dump($query->getResult());
    return $query->getResult();

答案 1 :(得分:1)

此行发生此错误:select('count(p), p.terrain')您尝试使用不再存在的p别名。 select方法会覆盖createQueryBuilder()的默认别名。为避免这种情况,请改用addSelect或明确指定from方法。 试试这个:

public function getTest(\Gp\UserBundle\Entity\User $user){
return $this->createQueryBuilder('p')
->addSelect('count(p), p.terrain')
->where('p.user = :user')
->setParameter('user', $user)
->groupBy('r.terrain')
->getQuery()
->getResult();

}

或者这个:

public function getTest(\Gp\UserBundle\Entity\User $user){
return $this->createQueryBuilder('p')
->select('count(p), p.terrain')
->from('YourBundle:YourEntity', 'p')
->where('p.user = :user')
->setParameter('user', $user)
->groupBy('r.terrain')
->getQuery()
->getResult();
}

答案 2 :(得分:0)

如何使用count和group执行原始查询:

连接到您的经理并建立新连接:

$manager = $this->getDoctrine()->getManager();
$conn = $manager->getConnection();

创建您的查询并获取fetchAll:

$result= $conn->query(
'select count(p.id) foobar, p.myid from foobartable p group by p.myid'
)->fetchAll();

从结果中获取数据:

$this->appendStringToFile("first row foobar is: " . $result[0]['foobar']);