Как составить критерии со сложным запросом в фреймворке Yii? - PullRequest
5 голосов
/ 26 октября 2010

У меня такой запрос:

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 ]

7 голосов
/ 29 октября 2010

Вы все еще можете построить это утверждение с помощью 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, но при этом можно было бы получить некоторые преимущества: связывание параметров, критерии объединения, добавление дополнительных критериев и т. Д.

6 голосов
/ 26 октября 2010

Пока ваш простой SQL работает, вы в безопасности.Много раз мне приходилось выбрасывать Active Record и просто выполнять работу по-старому.

Я пытался перевести этот запрос в читаемую конструкцию CDbCriteria.Плохая идея.Yii отстой, когда дело доходит до запроса сложных данных.

1 голос
/ 27 октября 2010

Ответ можно найти здесь: 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 правильно, что иногда вам приходится выбрасывать активную запись в окно.Это особенно актуально, если вы делаете массовые обновления, где циклическая обработка многочисленных моделей ужасно неэффективна.

0 голосов
/ 05 сентября 2012

Я использую 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>
    )
);

Я не проверял, как *Здесь можно ввести 1008 *.

Используя области действия, вы также можете вставить несколько более сложных критериев и при этом сохранить условие поиска читабельным.

Это довольно мощно.Я еще не видел полный «учебник» по этому поводу;Я вроде сделал вывод из исходного кода.

0 голосов
/ 06 апреля 2012

Просто используйте CSqlDataProvider http://www.yiiframework.com/doc/api/1.1/CSqlDataProvider

Отказ от ответственности: я знаю, что это не точный ответ на этот конкретный вопрос, но он может помочь обойти поставленную проблему.Я подозреваю, что основная цель этого вопроса - получить способ использовать CGridView, CListView и т. Д. С произвольным SQL.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...