Как я могу написать счетчик SQL с предложением group by, используя Propel ORM в Symfony? - PullRequest
3 голосов
/ 01 июня 2009

Как мне написать следующий SQL-запрос, используя Propel ORM?

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

Ответы [ 3 ]

2 голосов
/ 17 мая 2010

Это не запрос, который приведет к значимым гидратированным Bird объектам, так как вы выбираете только столбец species и количество этих видов. Так что «сырой» SQL-запрос, как предположил Колин, , вероятно, будет лучшим способом для этого - но не гидратируйте в конце, просто получите данные из результирующего PDOStatement.

Если бы species было ссылкой на таблицу Species, вы могли бы работать оттуда: гидрировать Species объекты с дополнительным столбцом для подсчета количества птиц по видам. Если вы используете Symfony до версии 1.2, я настоятельно рекомендую плагин DbFinder , поскольку он значительно упрощает работу с 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, перенес большую часть его функциональности и добавил больше, поэтому приведенный выше код работает в Propel 1.5 без дополнительных плагин.

1 голос
/ 04 июня 2009
$c = new Criteria();
$c->addAsColumn('cnt', "count(*)");
self::addSelectColumns($c);
$c->addGroupByColumn(BirdPeer::SPECIES);

но вы должны будете выполнить пользовательское увлажнение, если вам нужно подсчитать (*) для ваших заполненных объектов.

0 голосов
/ 01 июня 2009

Мне было трудно найти один документ по критериям Propel (там, похоже, нет документа API), поэтому я обычно использую список в главе 8 книги Symfony; но я понятия не имею, является ли это всеобъемлющим или нет.

Но то, что вы можете сделать, это напрямую передавать 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);

Я не думаю, что когда-либо сам использовал это, хотя мог бы.

...