2011-04-24 80 views
5

如何使用Cake語法編寫SQL子查詢? 我知道如何編寫簡單的查詢,但我無法處理子查詢。CakePHP和子查詢

這是原始查詢:

SELECT Assumption.id, Referee.id, Referee.first_name, Referee.second_name 
FROM referees AS Referee 
INNER JOIN (

    SELECT a.id, a.referee_id 
    FROM assumptions a 
    WHERE a.season_id =7 
) AS Assumption ON Referee.id = Assumption.referee_id 

回答

6

既然你聽不懂的語法,這是實際的查詢:

$records = $this->Referee->find('all', array(
       'fields' => array(
        'Assumption.id', 'Referee.id', 'Referee.first_name', 'Referee.second_name' 
        ), 
       'joins' => array(
        array(
         'table' => 'assumptions', 
         'alias' => 'Assumption', 
         'type' => 'INNER', 
         'foreignKey' => false, 
         'conditions' => array('Referee.id = Assumption.referee_id', 'Assumption.season_id = 7'), 
         ), 
       ), 
      ) 
     ); 

將會產生這個查詢:

SELECT 
    `Assumption`.`id`, 
    `Referee`.`id`, 
    `Referee`.`first_name`, 
    `Referee`.`second_name` 
FROM `referees` AS `Referee` 
INNER JOIN assumptions AS `Assumption` 
    ON (`Referee`.`id` = `Assumption`.`referee_id` 
     AND `Assumption`.`season_id` = 7) 

其中提供您正在尋找的結果。

輸出示例:

Array 
(
    [0] => Array 
     (
      [Assumption] => Array 
       (
        [id] => 1 
        [0] => Array 
         (
          [id] => 1 
          [season_id] => 7 
          [referee_id] => 1 
          [name] => SomeAssumpton 
         ) 

       ) 

      [Referee] => Array 
       (
        [id] => 1 
        [first_name] => Ref 
        [second_name] => one 
       ) 

     ) 

) 
+0

這產生簡單的查詢,產生不必要的響應。我應該重現那個子查詢。 – 2011-04-24 18:38:56

+0

由於您無法理解語法,因此我爲您編寫了代碼。它會產生你正在尋找的結果。 – 2011-04-24 22:34:07

+1

如果你想要你的EXACT子查詢,你唯一的其他選擇就是使用:'$ this-> Referee-> query('{你的SUB-QUERY HERE}');'因爲CakePHP沒有子查詢語法你想要寫他們的方式。 – 2011-04-25 01:54:19

1

打完似乎像年(幾個小時),閱讀蛋糕源...如果你想簡單地鍵入您的子查詢到你的蛋糕條件......

它使用PHP stdClass已經不是一個數組項...它只會轉儲你的「價值」進入查詢......

$subquery = new stdClass(); 
    $subquery->type = "expression"; 
    $subquery->value = "Product.id IN (select product_id from product_categories where category_id='$category_id' or belongs_to='$category_id')"; 

    $options['conditions'][] = $subquery; <- dump the class into your conditions array! 

做普通查詢 $這個 - >表 - >找到(「所有」, $選項)

實例:(正常蛋糕,子查詢的quickfix)

//only from my vendor 
    $options['conditions']['collection_id'] = $vendor_id; 

    //inner join to CollectionProduct 
    $options['joins'][0] = array(
     "table" => "collection_products", 
     "alias" => "CollectionProduct", 
     "type" => "INNER", 
     "conditions" => array(
      "Product.id = CollectionProduct.product_id", 
     ), 
    ); 

    //show only from current category 
    if ($category_id) { 
     $subquery = new stdClass(); 
     $subquery->type = "expression"; 
     $subquery->value = "Product.id IN (select product_id from product_categories where category_id='$category_id' or belongs_to='$category_id')"; 
     $options['conditions'][] = $subquery; 
    } else { 
     //get 18 random items... no category selected? 
     $options['limit'] = 18; 
    } 

    return $this->find('all', $options); 
+2

這就是幕後發生的事情,但正確的做法是遵循[食譜手冊]中的說明(http://book.cakephp.org/view/1030/Complex-Find-Conditions)。 – 2011-10-07 19:31:49

+1

如果你轉到你的鏈接並進入「子查詢」,你將看到巨大的開銷,生成上面顯示的一行SQL,這是簡短而甜蜜的。有很多查詢「不能」的蛋糕。如果你做多嵌套子查詢想象食譜會有多可怕。 – duante 2011-10-07 21:39:17

+1

此方法節省空間的唯一原因是因爲子查詢是明確寫入的。 OP特別聲明他們想要使用蛋糕方法。如果你不關心的話,最簡單的路線是簡單地使用$ this-> Model-> query()。同意,指南的方法很長,但這對示例代碼的作者沒有做出最大的工作沒有幫助。 – 2011-10-07 21:55:42

2

cdburgess的答案是這種情況的正確的;它以最簡單,最直接的方式解決問題。

這就是說,當解決執行子查詢的一般問題時,食譜記錄了preferred solution to the subquery problem。這不是很優雅,但是這是指南所說的做法。

或者你可以非常小心,只要做一個$ this-> Model-> query()。

+0

如果它不回答問題,這是不正確的。給予無關的答案並不能使答案正確。如果問題是,我如何查詢cakephp中的關係,那麼這將是正確的答案。 – Nemesis02 2016-01-26 17:36:16

+0

查克伯吉斯絕對回答OP的問題 - 他的方法甚至以更有效的方式產生正確的結果。如果有更好的解決方案,沒有理由對它是否使用子查詢進行挑剔。 – 2016-01-26 17:50:27

+1

他的問題很可能只是他被呈現的情況的一個例子。查詢可能會比這更復雜,比如我的例子。我有三個模型,a,b和c,a有多對多的b,它包含一個帶有數據透視表的類型,c與a有多對一的關係。如果我需要一個報告,其中c的類型是一個特定的值,那麼當它執行報告時,它將返回重複值,對於每個關係都會返回1,因爲它必須在檢查類型之前加載它。像他描述的一個真正的子查詢可以解決這個問題,而不是查克說的答案。 – Nemesis02 2016-01-27 20:47:20