2013-04-16 73 views
1

我有以下代碼:主義限制打破我的查詢?

$params = array(); 
$query_questions_visibles = questionTable::getInstance()->createQuery("q") 
    ->select("q.*, ua.*, a.*, u.*, c.*") 
    ->leftJoin("q.Answers a") 
    ->leftJoin("a.UserAnswers ua") 
    ->Where("q.blocked = false") 
    ->andWhere("ua.user_id = :user_id") 
->orderBy("q.id DESC") 
->groupBy("q.id"); 

    //Subquery --> Calculates when a question is active or not  
    $format = sfConfig::get("app_datetime_format"); 
    $active_time = date($format, strtotime(sfConfig::get("app_question_active_time"))); 
    $sub_query_is_active = $query_questions_visibles->createSubQuery() 
      ->select("MAX(ua0.created_at)") 
      ->from("question q0") 
      ->leftJoin("q0.Answers a0") 
      ->leftJoin("a0.UserAnswers ua0") 
      ->where("q0.id = q.id");     
    $query_questions_visibles->addSelect("COALESCE((".$sub_query_is_active.") > :active_time, false) as Active"); 

//Set param values 
$params["user_id"] = $guardUser->id; 
$params["active_time"] = $active_time; 

$result = $query_questions_visibles->execute($params); 

上面的代碼按預期工作。

生成的SQL是完整的作品:

SELECT q.id AS q__id, q.user_id AS q__user_id, q.category_id AS q__category_id, q.gender_restriction AS q__gender_restriction, q.question AS q_question, q.photo AS q_photo, q.latitude AS q_latitude, q.longitude AS q_longitude, q.multiple AS q_multiple, q.blocked AS q_blocked, q.created_at AS q__created_at, q.updated_at AS q__updated_at, a.id AS a__id, a.question_id AS a__question_id, a.text AS a_text, u.id AS u_id, u.user_id AS u__user_id, u.answer_id AS u__answer_id, u.created_at AS u__created_at, u.updated_at AS u__updated_at, COALESCE((SELECT MAX(u2.created_at) AS u2__0 FROM question q2 LEFT JOIN answer a2 ON q2.id = a2.question_id LEFT JOIN user_answer u2 ON a2.id = u2.answer_id WHERE (q2.id = q.id)) > :active_time, 0) AS u2__0 FROM question q LEFT JOIN answer a ON q.id = a.question_id LEFT JOIN user_answer u ON a.id = u.answer_id WHERE (q.blocked = 0 AND u.user_id = :user_id) GROUP BY q.id ORDER BY q.id DESC

但是,如果我想限制的結果,我修改端線爲:

$query_questions_visibles->limit(10); 
$result = $query_questions_visibles->execute($params); 

主義拋出一個錯誤:

SQLSTATE[HY093]: Invalid parameter number: number of bound variables does not match number of tokens

at Doctrine_Connection->execute('SELECT DISTINCT q2.id FROM question q2 LEFT JOIN answer a2 ON q2.id = a2.question_id LEFT JOIN user_answer u2 ON a2.id = u2.answer_id WHERE q2.blocked = 0 AND u2.user_id = :user_id GROUP BY q2.id ORDER BY q2.id DESC LIMIT 10', array('user_id' => '1', 'active_time' => '2013-03-17 17:12:12')) in SF_ROOT_DIR\lib\vendor\symfony\lib\plugins\sfDoctrinePlugin\lib\vendor\doctrine\Doctrine\Query.php line 1290 ...

我的目的只是限制查詢到10個結果,¿哪裏是我的COALESCE和MAX功能子查詢? ¿爲什麼有一個我從未指定過的SELECT DISTINCT? ¿爲什麼只選擇q.id?

我整天想弄明白,我沒有答案...... 任何想法,爲什麼設置限制原因造成的?

回答

1

當您添加limit()的學說查詢然後學說內部建立實際上是兩個查詢。第一個根據查詢條件選擇一組有限的不同ID。第二個查詢選擇實際對象,將select限制爲使用第一個查詢找到的id。

與您的查詢的問題是,您使用select部分,這是不是在第一個查詢中使用的內部PARAMS。

我想到的唯一解決方案是將active_time參數的值直接添加到選擇部分,而不使用命名參數。這可能不是最好的解決方案,但我現在無法想象另一種解決方案。該addSelect()不接受額外的參數,如where()確實可能解決這個問題(與where()你可以使用:->where('field > ?', $value))。

+0

嗨@Michal,它的怪異,我一直在使用一個名爲PARAMS和subquerys和IR作品很多類似'Doctrine_Querys'。只有這個有問題。 我真正的查詢大概是這個的3到4倍,我需要使用命名參數,因爲我使用了許多subquerys。 有沒有其他想法? – Pipe

+1

在其他情況下,你是否在'select'部分**和** a'limit'語句中使用了命名參數?複雜性(幾乎)與你將使用params或沒有關係(將值直接放在查詢中)無關。使用命名參數更像是「學說的方式」,但如果沒有其他方法,您可能需要刪除它們。 –

+0

是的,我使用相同的子查詢來計算問題在其他查詢中是否處於活動狀態,而另一個大型查詢也使用了限制,並且工作正常......這很奇怪。 回顧我目前的查詢,只有一個具有命名參數的addSelect()(與例子相同)。 我有其他人喜歡'addSelect(「(」。otherSubquery-> getDql()。「)作爲值」)';在'otherSubquery'中也有命名參數。 真的是一個好主意替換:'COALESCE((「。$ sub_query_is_active。」)>:active_time' for'COALESCE((。「$ sub_query_is_active。」)> $ active_time'?這可能是一個安全問題? – Pipe