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, 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加入 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]:无效的参数号:绑定变量的数量与标记的数量不匹配

在 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')) 在 SF_ROOT_DIR\ lib\vendor\symfony\lib\plugins\sfDoctrinePlugin\lib\vendor\doctrine\Doctrine\Query.php 第 1290 行 ...

我的目的只是将查询限制为 10 个结果,¿我的带有 COALESCE 和 MAX 函数的子查询在哪里?¿ 为什么有一个我从未指定的 SELECT DISTINCT?¿ 为什么只选择 q.id?

我花了一整天的时间试图弄清楚,我没有答案......任何想法为什么设置限制会导致这种情况?

4

1 回答 1

1

当您添加limit()到 Doctrine 查询时,Doctrine 内部实际上会创建两个查询。第一个根据您的查询条件选择一组有限的不同 id。第二个查询选择将选择限制为第一个查询找到的 id 的实际对象。

您的查询的问题是您在select零件内部使用了参数,而第一个查询中未使用该参数。

我想到的唯一解决方案是将active_time参数的值直接添加到选择部分,而不使用命名参数。这可能不是最好的解决方案,但我现在想不出一个不同的解决方案。addSelect()不接受像where()dos 这样可以解决问题的附加参数(您where()可以使用:)->where('field > ?', $value)

于 2013-04-17T10:41:30.333 回答