2014-07-07 2 views
1

크고 복잡한 논리가 포함 된 큰 데이터 레코드 필터가있는 yii 기반 응용 프로그램이 있습니다. 올바른 SQL 쿼리를 작성하고 테스트했습니다.yii cdbcriteria with join, group by 및 complex where 절

$filtered_records = ModelClass::model()->findAllBySql($sql, $params); 

을하지만 내 문제는 CDbCriteria을 사용하는 응용 프로그램 백엔드를 작성하는 것입니다 :

SELECT 
     c.`customer_id`  AS 'customer_id' 
    , c.`status_id`   AS 'status_id' 
    , c.`customer_name`  AS 'customer_name' 
    , BIT_OR(r2c.`role_id`) AS 'roles_mask' 
FROM 
    `customers` AS c 
LEFT JOIN 
    `roles2customers` AS r2c 
ON 
    c.`customer_id` = r2c.`customer_id` 
WHERE 
     IF( :status_mask = 0 
      , c.`status_id` = 0 
      , c.`status_id` & :status_mask <> 0 
     ) 
    AND c.`customer_id` <> :customer_id 
    AND c.`customer_name` LIKE concat(:customer_name, '%') 
GROUP BY 
    c.`customer_id` 
HAVING 
    IF( :role_mask = 0 
     , BIT_OR(r2c.`role_id`) = 0 
     , BIT_OR(r2c.`role_id`) & :role_mask <> 0 
    ) 
ORDER BY 
    c.`customer_name` ASC 
LIMIT 
    :offset, :count 

이 쿼리는 간단한 액티브 방식 findAllBySql 제대로 작동합니다. 그래서 findall은 방법에 마우스 오른쪽 기준을 구축 개체와 전달해야

$criteria = new CDbCriteria(); 
$filtered_records = ModelClass::model()->findAll($criteria); 

나는 CDBCriteria reference을 열어 많은 간단한 예제를 보았다,하지만 .. 어떻게 가입 및 지정할 수 있습니다 내 경우에는 기준을 통해 작업하는 데 문제가 있습니까?

내 코드 :

$criteria = new CDbCriteria(); 
$criteria->condition = " 
    c.customer_id AS 'customer_id', 
    c.status_id AS 'status_id', 
    c.customer_name AS 'customer_name', 
    BIT_OR(r2c.role_id) AS 'roles_mask' 
"; 
$criteria->offset = $offset; 
$criteria->limit = $limit; 
// how can I make valid r2c relation and group by via criteria? 
// and all another sql parts... 

답변

3

GROUP BYHAVING 부품 condition, offsetlimit와 같은 방법으로 직접 부착됩니다

$criteria->group ='t.customer_id' 
$criteria->having='IF( :role_mask = 0 
    , BIT_OR(r2c.`role_id`) = 0 
    , BIT_OR(r2c.`role_id`) & :role_mask <> 0 
)' 

LEFT JOIN는 조금 더 복잡하지만, 할 수 있습니다 사용 완료 with :

$criteria->with=array(
    'roles2customers'=>array(
    'alias'=>'r2c', 
    'joinType'=>'LEFT JOIN', 
    'condition'=>' 
      IF( :status_mask = 0 
      , t.`status_id` = 0 
      , t.`status_id` & :status_mask <> 0 
     ) 
     AND t.`customer_id` <> :customer_id 
     AND t.`customer_name` LIKE concat(:customer_name, '%') 
    ', 
) 
) 

이것은 ModelClass에 기본 관계 roles2customers을 설정하는 데 달려 있습니다.