标准双向加入?

时间:2011-12-05 15:31:51

标签: join symfony1 symfony-1.4 criteria propel

我正在使用推进ORM从事symfony项目。在我的模型中,我有一个表,其中的元素可以通过另一个表(链接表)与同一个表的许多元素链接。有些代码会更好地解释:

table1:
    id_element: integer;
    [...]

和链接表:

 link_table:
     id1: fk to table1;
     id2: fk to table1;

我需要使用Propel Criteria构建一个查询,该查询返回具有特定元素的所有相关元素。问题是我想要指定的元素,可以像在id1字段中一样,在链接表的id2字段中。

现在我的一些标准定义代码(显然不能正常工作)

$c = new Criteria();
$c->addJoin($linkTable::ID1,$table::ID);
$c->addJoin($linkTable::ID2,$table::ID);
$c->addOr($linkTable::ID1,$specific_id);
$c->addOr($linkTable::ID2,$specific_id);
$result = $table->doSelect($c);

这是一个像我想要生成的SQL:

SELECT * FROM table
    WHERE table.ID IN
        (SELECT link_table.ID1 FROM link_table
            WHERE link_table.ID2 = "the id that i want"
        )
    OR table.ID IN 
        (SELECT link_table.ID2 FROM link_table
            WHERE link_table.ID1 = "the id that i want"
        )

所以我必须做2个连接,链接表的每一个连接一个?有没有办法做一个" or-join"?请帮帮我!

非常感谢您的时间:)

4 个答案:

答案 0 :(得分:0)

也许我不太清楚你需要什么...你有一个表的两个外键都链接到同一个表,所以id,你想要一个or-join。为什么不分为两个标准,因此有两个选择?

答案 1 :(得分:0)

大声思考 - 看起来在功能上与此相同:

SELECT
    *
FROM
    my_table
LEFT JOIN
    link_table lt1 ON (lt1.id1 = my_table.id)
LEFT JOIN
    link_table lt2 ON (lt2.id2 = my_table.id)
WHERE
    lt1.id2 = X
OR
    lt2.id1 = X

如果它是相同的(显然要检查)那么构建查询应该更容易。另外,如果可以的话,尝试使用ModelCriteria - 我怀疑在Propel 2中将不推荐使用Criteria,并且提前做好计划是个好主意。

答案 2 :(得分:0)

避免使用Criteria,正如halfer所说,最好使用ModelCriteria及其API。请阅读以下文档以获取更多信息:http://www.propelorm.org/reference/model-criteria.html

答案 3 :(得分:0)

最后我发现了一种使用标准的方法:

$c = new Criteria();
    $q1 = new Criteria();
    $q1->add($linkPeer::ID1,$my_value);
    result1 = $linkPeer->doSelect($q1);
    foreach($result1 as $result){
        ids1[] = $result->getID();
    }
    $q2 = new Criteria();
    $q2->add($linkPeer::ID2,$my_value);
    result2 = $linkPeer->doSelect($q2);
    foreach($result2 as $result){
        ids2[] = $result->getID();
    }
$ids = array_merge($ids1,$ids2);
$c->add($tablePeer::ID,$ids,Criteria::IN);
$totalResult = $tablePeer->doSelect($c);

也许不是最好的方式,但工作正常。

非常感谢您的回答!!