Бывают ситуации, когда нужно получить запрос 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
);
что мне кажется логичнее ?
Апрель 22nd, 2010 at 19:59
addMultipleJoin как раз так и работает
Апрель 23rd, 2010 at 09:23
Все верно, только метод этот появился в Propel 1.4
Сентябрь 29th, 2011 at 01:23
Ох уж эти LEFT JOIN. Один раз наткнулся не непонятный случай, так и не смог понять в чем дело.
SELECT t1.field1, t2.field2
FROM t1 LEFT JOIN t2 ON t1.id = t2.id
привело к повисанию MySQL на таблицах t1 и t2, содержащих более 10000 записей каждая
в тоже время
SELECT t1.field1, t2.field2
FROM t1, t2
WHERE t1.id = t2.id
отработало мгновенно, хотя декартово произведение по логике намного затратнее.
Май 4th, 2009 at 22:22
ну это уже к разработчикам :). Хотя так действительно логичнее сделать, а главное удобнее.
Май 17th, 2009 at 12:20
Спасибо! Наконец-то…
Май 17th, 2009 at 14:33
А как быть с более сложными условиями внутри INNER JOIN?
Например, Criteria::CUSTOM, или когда более сложное логическое условие вместе с OR?