yii cdbcriteria with join,group by和complex where子句

时间:2014-07-07 11:02:36

标签: sql yii

我有yii驱动的应用程序和大数据记录过滤器,其中包含大而复杂的逻辑。我写了正确的SQL查询并测试了它。

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

此查询适用于简单的ActiveRecord方法findAllBySql:

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

但我的问题是使用CDbCriteria编写应用程序后端。所以我需要建立正确的标准对象并将其传递给 findAll 方法:

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

我打开了CDBCriteria reference,看到了很多简单的例子,但是......在我的情况下如何通过条件指定JOIN和HAVING操作?

我的代码:

$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...

1 个答案:

答案 0 :(得分:3)

GROUP BYHAVING部分可以与conditionoffsetlimit相同的方式直接连接:

$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, '%')
    ',
  )
)

这取决于您在roles2customers中设置基本关系ModelClass