CakePHP найти с LEFT JOIN и generate_series - PullRequest
2 голосов
/ 03 апреля 2012

По существу, возможно ли это, и если да, то как выполнить следующий код без использования метода raw query () в CakePHP 2.0.6. Я использую PostgreSQL (функция generate_series()). Итак, как вы делаете этот запрос CakePHP способом?

$sql = "
    SELECT new_rank FROM generate_series(1,999) AS new_rank
    LEFT JOIN tasks ON tasks.rank = new_rank
    WHERE tasks.rank IS NULL LIMIT 1
";
$data = $this->Task->query($sql);

EDIT Один пользователь сказал, что я могу попытаться использовать вызов find для Task и правое соединение с generate_series (). Вот моя попытка сделать это. Этот код выдает ошибку, потому что CakePHP помещает двойные кавычки вокруг аргументов функции для generate_series. Интересно, как я могу заставить его этого не делать?

$data = $this->Task->find('all', array(
   'conditions' => array('Task.rank' => null),
   'limit' => 1,
   'recursive' => -1,
   'fields' => 'new_rank',
   'joins' => array(
      array(
          'table'=>'generate_series(1,999)',
          'alias'=>'new_rank',
          'type'=>'RIGHT',
          'conditions' => array(
            'tasks.rank'=>'new_rank'
          )
      )
   )
));

Какие продукты следующие SQL:

SELECT "Task"."new_rank" AS "Task__new_rank"
FROM "tasks" AS "Task"
RIGHT JOIN generate_series("1,999") AS "new_rank" ON ("tasks"."rank" = 'new_rank')
WHERE "Task"."rank" IS NULL LIMIT 1

1 Ответ

1 голос
/ 04 апреля 2012

То, что вы, вероятно, ищете, находится в DboSource::expression(). Это в основном позволяет вам сделать выражение SQL без экранирования Cake. Обязательно очистите входы.

Чтобы оно отображалось как поле, вы можете попробовать добавить его к ключу поля в вашем массиве опций:

$ds = $this->Task->getDataSource();
$this->Task->find('all', array(
  'fields' => $ds->expression('generate_series(1,999) AS new_rank')
));

Если это не сработает, вы всегда можете попробовать DboSource::rawQuery(), который не ускользнет что-нибудь , afaik.

...