1

ブログ投稿のリストがあるページに、各ブログ投稿のコメント数(カテゴリ、日付、作成者など)を表示したいと思います。次のmysqlクエリをpropelで作成するにはどうすればよいですか?

SELECT post.id, post.title, post.more_columns , COUNT(comments.post_id) AS numofcomments FROM post INNER JOIN comments ON post.id = comments.post_id GROUP BY post.id, post.title, post.more_columns

ここで、postはブログテーブルとコメントであり、post.idへの外部キーとしてpost_idを持つコメントのテーブルです。結果セットの列として「numofcomments」を取得できないようです。現在、私は非ORMアプローチを使用しています(これが私の最後の手段になります):

$con = Propel::getConnection(PostPeer::DATABASE_NAME);

    $sql = "SELECT post.* , COUNT(comments.post_id) AS numcomments FROM post INNER JOIN comments ON post.id = comments.post_id GROUP BY post.id";  
    $stmt = $con->prepare($sql);
    $stmt->execute();

    $result = PostPeer::populateObjects($stmt);
    return $result;

結果のPropel結果セットの「numofcomments」にアクセスするにはどうすればよいですか?

編集:私が知りたかったのは、Propelで上記のクエリをどのように書くことができるかです?私が今できることは、コメントテーブルの内部結合を使用して投稿テーブルを取得し、各投稿IDのコメントテーブルでdoCountを実行することです。これにより、Postテーブルに対して1つのクエリが発生し、commentsテーブルに対して多くのクエリが発生します。SQLクエリを最小限に抑えたいと思います。ありがとう :)

4

4 に答える 4

1

SELECT post.* , COUNT(comments.post_id) AS numcomments FROM post INNER JOIN comments ON post.id = comments.post_id GROUP BY post.id,post.secondcol,post.thirdcol;など、post。*を選択したため、postテーブルの個々の列をすべてリストするだけです。post.post_idだけでなく、すべての列をリストする必要があります。

交互に

SELECT post.*,sub.numcomments from post,
(select post.post_id as post_id,COUNT(comments.post_id) AS numcomments 
   FROM post INNER JOIN comments ON post.id = comments.post_id GROUP BY post.id) as sub
   where post.post_id = sub.post_id;

(3.より簡単な方法もありますが、今は忘れています。)

于 2009-08-03T17:57:16.973 に答える
1

カスタムクエリによって返されるオブジェクトに追加のデータをパックする場合は、ピアクラスのデフォルトのdoSelect()メソッドをオーバーライドして、クエリから返される各オブジェクトにこの追加のデータを追加できます。

投稿クラスでは、保護された変数を追加できます。これを「numComments」と呼びましょう。

class Post extends BasePost {
  protected $numComments;

  public function setNumComments($v)
  {
    $this->numComments = $v;
  }

  public function getNumComments()
  {
    return $this->numComments;
  }
  ...
}

次に、静的doSelectWithCount()メソッドのPostPeerクラスで次のようにします。

public static function doSelectWithCount() {
  $c = new Criteria();
  self::addSelectColumns($c); //add all columns from PostPeer
  $c->addAsColumn('numofcomments', 'COUNT('.CommentPeer::POST_ID.')');
  $c->addJoin(PostPeer::ID, CommentPeer::POST_ID, Criteria::LEFT_JOIN);
  $c->addGroupByColumn(PostPeer::ID);
  $c->addGroupByColumn(PostPeer::TITLE);
  // ...
  // more group-by columns if needed
  $rs = PostPeer::doSelectRS($c);

  $posts = array();
  while ($rs->next()) {
    $post = new Post();
    $post->hydrate($rs);
    $post->setNumComments($rs->getInt(PostPeer::NUM_COLUMNS + 1));
    $posts[] = $post;
  }

  return $posts;
}
于 2009-08-06T22:20:19.973 に答える
0

これがSQLクエリの推進バージョンです。

$c = new Criteria();
// count comments with 
$c->addAsColumn('numofcomments', 'COUNT('.CommentPeer::POST_ID.')');
$c->addJoin(PostPeer::ID, CommentPeer::POST_ID, Criteria::LEFT_JOIN);
$c->addGroupByColumn(PostPeer::ID);
$c->addGroupByColumn(PostPeer::TITLE);
// you can add more groupby column here
//$c->addGroupByColumn(...more);
$this->posts = PostPeer::doSelect($c);

INNERJOINの代わりにLEFTJOINを使用する必要があります。なぜなら。内部結合を使用すると、コメントが1つ以上ある投稿にのみアクセスできます。左結合を使用すると、コメントのない投稿を選択できます。

これがお役に立てば幸いです。

于 2009-08-04T17:14:38.590 に答える
0

これはうまくいったことですが、それを行うには悲しい方法です:|

//inside a static function in class PostPeer:
$c = new Criteria();
self::addSelectColumns($c); //add all columns from PostPeer
$c->addJoin(PostPeer::ID, CommentPeer::POST_ID, Criteria::LEFT_JOIN);
$cu->addAsColumn('numofcomments', 'COUNT('.CommentPeer::POST_ID.')');
$cu->addGroupByColumn(PostPeer::ID);
$cu->addGroupByColumn(PostPeer::TITLE);
:
:
//more group-by columns if needed
return PostPeer::doSelectStmt($c);

次に、テンプレートで次のように配列にアクセスします。

<div id="title">
   <?php echo post_array[1] ?>
</div>
//...and so on for other Post fields

「post_array[1]」の代わりに「post_array['title']」をテンプレートに記述できるように、モデルで配列の関連付けを行うにはどうすればよいですか?また、この回避策は安全ですか?より良い提案。Propel1.3を使用しています

于 2009-08-05T13:45:27.047 に答える