propel 사용 SQL 쿼리 (내부 조인 + count + group by)
문제
블로그 게시물 목록이있는 페이지에 각 블로그 게시물 (카테고리, 날짜, 저자 등)에 대한 주석 수를 표시하고 싶습니다. Propel에 다음 mySQL 쿼리를 어떻게 작성합니까?
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를 게시하는 댓글 테이블입니다. 결과 세트의 열로 'numofcomments'를 얻을 수없는 것 같습니다. 현재 나는 비 관습 접근법을 사용하고 있습니다 (내 최후의 수단이 될 것입니다).
$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;
결과 ProCELLESTET에서 'numofcomments'에 어떻게 액세스 할 수 있습니까?
편집 : 내가 알고 싶은 것은 Propel에 위의 쿼리를 어떻게 작성할 수 있습니까? 내가 지금 할 수있는 일은 주석 테이블에 내부 조인이있는 포스트 테이블을 얻은 다음 각 Post-ID에 대한 주석 테이블에서 docount를 실행하는 것입니다. 이로 인해 포스트 테이블에 대한 1 개의 쿼리와 주석 테이블에 대한 많은 쿼리가 발생합니다. SQL 쿼리를 최소로 줄이고 싶습니다. 감사 :)
해결책 4
글쎄, 이것은 효과가 있었지만 슬픈 방법은 다음과 같습니다. |
//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']]를 쓸 수 있도록 모델에서 배열 협회를 만드는 방법은 무엇입니까? 또한이 해결 방법은 안전합니까? 더 나은 제안. Propel 1.3을 사용하고 있습니다
다른 팁
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_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. 그리고 더 쉬운 방법도 있습니다. 지금 잊어 버렸습니다 ..)
사용자 정의 쿼리로 반환 된 객체에 추가 데이터를 포장하려면 피어 클래스의 기본 doselect () 메소드를 무시하고 쿼리 에서이 추가 데이터를 반환되는 각 객체에 추가 할 수 있습니다.
게시물 클래스에서 보호 된 변수를 추가하여 "NumComments"라고 부를 수 있습니다.
class Post extends BasePost {
protected $numComments;
public function setNumComments($v)
{
$this->numComments = $v;
}
public function getNumComments()
{
return $this->numComments;
}
...
}
그런 다음 정적 복용량 위장 () 메소드의 연기 수업에서 :
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;
}
다음은 SQL 쿼리의 Propel 버전입니다.
$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);
대신 왼쪽 조인을 사용해야합니다. 왜냐하면. 내부 조인을 사용하면 최소한 하나의 주석이있는 게시물에만 액세스 할 수 있습니다. 왼쪽 가입을 사용하면 무인 게시물을 선택할 수 있습니다.
이게 도움이 되길 바란다.