Бывают ситуации, когда нужно получить запрос 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


Май 4th, 2009 at 15:40
Сам с этим сталкивался, код такой же)
А вы можете сказать почему нужно указывать именно перекрестно:
$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
);
что мне кажется логичнее ?
Май 4th, 2009 at 22:22
ну это уже к разработчикам
. Хотя так действительно логичнее сделать, а главное удобнее.
Май 17th, 2009 at 12:20
Спасибо! Наконец-то…
Май 17th, 2009 at 14:33
А как быть с более сложными условиями внутри INNER JOIN?
Например, Criteria::CUSTOM, или когда более сложное логическое условие вместе с OR?