如何在Symfony中使用Propel ORM编写带有group by子句的SQL计数?

时间:2009-06-01 03:39:50

标签: php sql symfony1 propel

如何使用Propel ORM编写以下SQL查询?

SELECT species, COUNT(*) FROM Bird GROUP BY species;

3 个答案:

答案 0 :(得分:2)

这不是一个会产生有意义的水合Bird对象的查询,因为您只选择species列和这些物种的数量。所以a "raw" SQL query as Colin suggested可能是最好的方式 - 但最后不要保持水分,只需从结果PDOStatement中获取数据。

如果species是对Species表的引用,您可以从那里开始工作:水合Species个对象,每个物种的鸟类数量增加一列。如果您使用Symfony 1.2版本,我强烈推荐DbFinder plugin,因为它极大地简化了Criteria的使用,并且有方法可以选择一个补充列:

$speciesQuery = DbFinder::from('Species')->
  join('Bird')->
  groupBy('Bird.Id')->
  withColumn('COUNT(Bird.Id)', 'NbBirds');

foreach ($speciesQuery->find() as $species) {
  echo $species->getName() . ": " . $species->getNbBirds() . " birds\n";
}

如果你使用Symfony 1.3或1.4,你应该将捆绑的Propel 1.4升级到Propel 1.5,其中DbFinder的创建者FrançoisZaniotto移植了它的大部分功能并增加了更多,所以上面的代码在Propel 1.5中工作而没有额外的插件。

答案 1 :(得分:1)

$c = new Criteria();
$c->addAsColumn('cnt', "count(*)");
self::addSelectColumns($c);
$c->addGroupByColumn(BirdPeer::SPECIES);

但是如果您需要对填充的对象进行计数(*),则需要进行自定义保湿。

答案 2 :(得分:0)

我发现很难找到关于Propel Criteria的单个文档(似乎没有关于它的API文档)所以我通常使用symfony书的第8章中的列表;但我不知道这是否全面。

但你可以做的是直接将SQL提供给Propel。以下内容是根据http://propel.phpdb.org/docs/user_guide/chapters/FindingObjects.html中的示例修改的:

    $con = Propel::getConnection(DATABASE_NAME);

    // if not using a driver that supports sub-selects
    // you must do a cross join (left join w/ NULL)
    $sql = "SELECT species, COUNT(*) FROM Bird GROUP BY species";

    $stmt = $con->createStatement();
    $rs = $stmt->executeQuery($sql, ResultSet::FETCHMODE_NUM);

    return parent::populateObjects($rs);

我不认为我曾经以这种方式使用它,尽管我可能会这样。