Май 02 2009

Left Join с несколькими условиями для Propel Criteria

Раздел: Symfonyingvar @ 19:16

Бывают ситуации, когда нужно получить запрос c оператором Left Join указав несколько условных выражений. Например:

SELECT * FROM news
LEFT JOIN news_type ON news.type_id = news_type.id AND YEAR(news.published_at) = YEAR(NOW())
WHERE news.is_published = 1 AND ...
LIMIT 10

Используя стандартную конструкцию Propel Criteria, получаем следующий код:

$c = new Criteria();
$c->add(NewsPeer::IS_PUBLISHED, true);
$c->addJoin(NewsPeer::TYPE_ID, NewsTypePeer::ID, Criteria::LEFT_JOIN);
$c->add(NewsPeer::DATE, "YEAR(" . NewsPeer::PUBLISHED_AT. ") = YEAR(NOW())", Criteria::CUSTOM);
....

Но результат не будет соответствовать нашему условию и это можно увидеть в сгененированном SQL-коде:

SELECT * FROM news
LEFT JOIN news_type ON news.type_id = news_type.id
WHERE news.is_published = 1 AND YEAR(news.published_at) = YEAR(NOW()) ...
LIMIT 10


В Propel 1.3 появилась возможность указать несколько условий для оператора Join. Правильный код будет таков:

$c = new Criteria();
$c->add(NewsPeer::IS_PUBLISHED, true);

$c->addJoin(
  array(NewsPeer::TYPE_ID, "YEAR(" .  NewsPeer::PUBLISHED_AT. ")"),
  array(NewsTypePeer::ID, "YEAR(NOW())"),
  Criteria::LEFT_JOIN
);

....

Источник: Propel 1.3:: More on Criteria:: Joins

Tags: ,

4 Responses to “Left Join с несколькими условиями для Propel Criteria”

  1. broderix says:

    Сам с этим сталкивался, код такой же)
    А вы можете сказать почему нужно указывать именно перекрестно:
    $c->addJoin(
    array(NewsPeer::TYPE_ID, «YEAR(» . NewsPeer::PUBLISHED_AT. «)»),
    array(NewsTypePeer::ID, «YEAR(NOW())»),
    Criteria::LEFT_JOIN
    );
    а не так:
    $c->addJoin(
    array(NewsPeer::TYPE_ID,NewsTypePeer::ID),
    array( «YEAR(» . NewsPeer::PUBLISHED_AT. «)», «YEAR(NOW())»),
    Criteria::LEFT_JOIN
    );
    что мне кажется логичнее ?

  2. ingvar says:

    ну это уже к разработчикам :) . Хотя так действительно логичнее сделать, а главное удобнее.

  3. Павел says:

    Спасибо! Наконец-то…

  4. Павел says:

    А как быть с более сложными условиями внутри INNER JOIN?
    Например, Criteria::CUSTOM, или когда более сложное логическое условие вместе с OR?

Leave a Reply