如何在Yii框架中使用复杂查询制作标准?

时间:2010-10-26 08:29:36

标签: php yii

我有这样的查询:

SELECT * FROM activity
WHERE (((userId = 1 OR userId IN(SELECT userId FROM follower WHERE followerId = 1))
AND activityType IN(1, 2, 3))
OR (targetId = 24 AND aType IN(1, 2, 3, 4, 5)))
ORDER BY id DESC;

我尝试使用model()->findAllBySql($sql)并且它有效。但是我想用CDbCriteria来制作它,如果你有其他解决方案让我知道它:D

5 个答案:

答案 0 :(得分:7)

您仍然可以使用CDbCriteria构建此语句,我认为......类似于:

$criteria=new CDbCriteria;
$criteria->condition = '
  (
    (
      userId = 1 OR 
      userId IN (SELECT userId FROM follower WHERE followerId = 1)
    )
    AND activityType IN(1, 2, 3)
  )
  OR (
    targetId = 24 
    AND aType IN(1, 2, 3, 4, 5)
  )
';
$criteria->order = 'id DESC';
$results=Activity::model()->findAll($criteria);

在这一点上,您可能只是编写一个常规的SQL语句,但这样做可能会有一些好处:绑定参数,合并条件,添加其他条件等。

答案 1 :(得分:6)

只要你的普通SQL工作,你就是安全的。很多时候我不得不抛弃Active Record,只是以更加理智的方式完成工作。

我尝试将此查询转换为可读的CDbCriteria结构。馊主意。当查询复杂数据时,Yii很糟糕。

答案 2 :(得分:1)

答案可以在这里找到: http://www.yiiframework.com/doc/guide/1.1/en/database.dao#executing-sql-statements

在你的情况下:

$sql = 'SELECT * FROM activity';
$sql .= 'WHERE (((userId = 1 OR userId IN(SELECT userId FROM follower WHERE followerId = 1))';
$sql .= 'AND activityType IN(1, 2, 3))';
$sql .= 'OR (targetId = 24 AND aType IN(1, 2, 3, 4, 5)))';
$sql .= 'ORDER BY id DESC';

$connection = Yii::app()->db;
$command = $connection->createCommand($sql);
$results = $command->queryAll();

@pestaa是对的,有时你必须把活动记录扔出窗外。如果您正在进行大规模更新,那么循环使用众多模型的效率非常低。

答案 3 :(得分:0)

只需使用CSqlDataProvider http://www.yiiframework.com/doc/api/1.1/CSqlDataProvider

免责声明:我知道这个具体问题的答案并不准确,但它可能有助于解决所提出的问题。我怀疑这个问题的主要目的是让任意SQL使用CGridView,CListView等。

答案 4 :(得分:0)

我将CDbCriteria用于我使用with功能的复杂查询。

您可以构建如下的复杂条件:

$dbCriteria->with=array(
   '<relation1>'=>array( 'condition'=>'<condition for given relation>',
        'with'=>array('<relation2:relation of relation1>'
            =>array(<conditions for relation2>)
        )
        'scopes'=><scopes for relation1>
    )
);

我还没有查看OR如何在这里发挥作用。

通过使用范围,您还可以插入一些更复杂的标准,并仍然可以保持搜索条件的可读性。

这非常强大。我还没有看到关于此的完整“教程”;我从源代码中得出结论。