2009-08-03 5 views
1

블로그 게시물 목록이있는 페이지에서 각 블로그 게시물에 대한 의견 수 (범주, 날짜, 작성자 등)를 표시하려고합니다. 어떻게 propel에 다음 mysql 쿼리를 작성합니까?Propel을 사용하는 Sql 쿼리 (inner join + count + group by)

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.id에 대한 외래 키로 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; 

이 어떻게 결과 추진 결과 집합에서 'numofcomments'에 액세스 할 수 있습니다 : 현재 나는 (내 마지막 수단이 될 것이다) 비 ORM 접근 방식을 사용하고 있습니다?

EDIT : 제가 알고 싶은 것은 Propel에서 위의 쿼리를 작성하는 방법입니다. 내가 할 수있는 일은 주석 테이블에 내부 조인이있는 게시 테이블을 만든 다음 각 게시 ID에 대한 주석 테이블에서 doCount를 실행하는 것입니다. 이로 인해 Post 테이블에 대한 1 개의 쿼리와 주석 테이블에 대한 많은 쿼리가 생성됩니다. SQL 쿼리를 최소한으로 줄이고 싶습니다. 이 게시물을 선택하기 때문에 감사합니다 :) 등

답변

0

그럼이 방법이 효과가 있지만 슬픈 방법입니다. 전 모델의 배열 관계를 어떻게해야합니까

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

내가 "템플릿"post_array [ '제목'] "쓰기 대신 할 수 있도록 :

//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); 

그런 다음 템플릿에 내가 같이 배열 액세스 post_array [1] "? 또한이 해결 방법은 안전한가요? 더 좋은 제안. Propel 1.3을 사용 중입니다

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_id 없습니다.

Alternativly

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; 

여기

+0

감사 @nos ...이는 그룹 별 쿼리를 올바르게 작성하지 않았지만 내 질문에 대한 근본적인 감독 이었지만 문제는 다릅니다. 나는 그것을 편집했다 ... 다시 확인할 수 있니? :) – fenderplayer

0

을 (가 ... 내가 지금 잊고있는,뿐만 아니라 3. 쉽게 방법) 당신의 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); 

내부 조인 대신 LEFT JOIN을 사용해야합니다. 때문에. 내부 조인을 사용하면 하나 이상의 주석이있는 게시물에만 액세스 할 수 있습니다. 왼쪽 결합을 사용하면 주석 처리되지 않은 게시물을 선택할 수 있습니다.

이 정보가 도움이되기를 바랍니다.

+0

$ this-> posts에서 'numofcomments'에 액세스 할 수 없습니다. 이 접근법은 아마도 맞춤 수화 방법을 필요로합니다. 어떻게해야할지 모르겠다. – fenderplayer

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; 
}