2011-12-05 45 views
1

我正在開發一個symfony項目,推動ORM。在我的模型中,我有一個表,其元素可以通過另一個表(鏈接表)與同一表的很多元素鏈接。一些代碼將更好地解釋:條件雙向加入?

table1: 
    id_element: integer; 
    [...] 

和鏈接表:

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

我需要建立與波輪條件的查詢返回我所有與特定元素相關的元素。問題是我想指定的元素可以像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」?請幫幫我!

非常感謝您的寶貴時間:)

+0

也許你應該重新考慮你的解決方案,這種遞歸行爲在關係型數據庫中不受鼓勵。你能否提供更多有關這個模型試圖代表什麼的信息。大多數時候,我發現自己對複雜的查詢幾乎總是意味着我沒有想到通過這個問題。 – guiman

+0

下面的表格表示一個過程。這些過程可以與其他過程相關聯,形成一個多對多的關係,並且這個關係必須像我一樣作爲鏈接表來實施(所以我的大學老師說過)。 –

回答

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); 

也許不是最好的方式,但做工精細。

非常感謝您的回答!

+1

循環中不必要的水合會使這個查詢變慢,這取決於迭代的次數。如果你想這樣做,我會用'doSelectStmt'(並在每個循環內進行必要的調整)將第4行和第10行的'doSelect'交換。 – halfer

0

也許我不很明白你需要什麼......你有都鏈接到同一表的表的兩個外鍵,所以ID ,並且你想要一個or-join。爲什麼不分成兩個標準和兩個選擇?

+0

,因爲作爲我的選擇操作的結果,我需要表中唯一實體的數組。 –

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 - 我懷疑Criteria將在Propel 2中被棄用,並且爲此提前計劃是一個好主意。