Доктрина 2 - Как добавить лимит в несколько addSelect - PullRequest
0 голосов
/ 01 января 2019

Проблема : получил Ошибка при запуске запроса

{
    "status": false,
    "error": {
        "classname": "Doctrine\\ORM\\Query\\QueryException",
        "message": "[Syntax Error] line 0, col 783: Error: Expected Doctrine\\ORM\\Query\\Lexer::T_CLOSE_PARENTHESIS, got 'LIMIT'"
    }
}

Как добавить limit в addSelect в запросе ниже.

 $qb = $this->em->createQueryBuilder();
    $qb->select("identity(igsm.group) as group_id,
    qp.id AS q_paper_id,
    qp.name AS q_name,
    qp.description AS q_description,        
    qp.marks,
    identity(qp.questionPaperStatus) AS qpStatus,
    qp.timeInMinutes as time_in_minutes,
    sa.marks as marks_obtained,
    sa.id AS assessment_id");
    $qb->addSelect("(SELECT IfElse(count(qps.id) > 0 , TRUE, FALSE) FROM Entity\QuestionPaper qps "
            . "WHERE qps.createdBy = :userId AND qps.id = qp.id) as flag");
    $qb->addSelect("(SELECT count(qpe.id) from Entity\QuestionPaperEvaluation qpe "
            . "where qpe.questionPaper = qp.id AND qpe.user = :userId) as student_evaluation_cnt");
    $qb->addSelect("(SELECT LOWER(ats.assignee) from Entity\AssessmentTimelineStatus ats, Entity\AssessmentStudentTimeline ast "
            . "WHERE ast.assessmentTimelineStatus = ats.id AND ast.user = igsm.user AND ast.assessment = qp.id "
            . "ORDER BY ats.id DESC LIMIT 1) AS assignee");
    $qb->addSelect("(SELECT identity(ast.assessmentTimelineStatus) from Entity\AssessmentTimelineStatus ats, Entity\AssessmentStudentTimeline ast "
            . "WHERE ast.assessmentTimelineStatus = ats.id AND ast.user = igsm.user AND ast.assessment = qp.id "
            . "ORDER BY ats.id DESC LIMIT 1) AS assessment_timeline_id");
    $qb->addSelect("(SELECT UPPER(ConcatWs(' ', ats.action,ats.item)) as assesment_submissions from Entity\AssessmentTimelineStatus ats, "
            . "Entity\AssessmentStudentTimeline ast WHERE ast.assessmentTimelineStatus = ats.id AND ast.user = igsm.user AND ast.assessment = qp.id "
            . "ORDER BY ats.id DESC LIMIT 1) AS action");
    $qb->from('Entity\QuestionPaperGroupStudentMap', 'qpgsm');
    $qb->innerJoin('Entity\InstituteGroupStudentMap', 'igsm', 'WITH', 'igsm.id=qpgsm.instituteGroupStudentMap');
    $qb->innerJoin('Entity\QuestionPaper', 'qp', 'WITH', 'qp.id=qpgsm.questionPaper AND qp.questionPaperStatus > 4');
    $qb->leftJoin('Entity\AssesmentSubmissions', 'sa', 'WITH', 'sa.assesmentId = qp.id AND sa.userId = igsm.user');
    $qb->leftJoin('Entity\PackageQuestionPaperHistory', 'pqph', 'WITH', 'pqph.questionPaperId = qp.id');
    $qb->where('igsm.user = :userId')->setParameter(':userId', $userId);
    $qb->andWhere("igsm.group IN (:GroupIds)")->setParameter(':GroupIds', explode(",", $groupId));
    $qb->orderBy('qpgsm.id', 'DESC');
    $qb->setMaxResults(1);
    $result = $qb->getQuery()->getResult();
    return $result;

Могу ли я поставить подзапрос индивидуально, хотя подзапрос зависит от основного запроса.Как я могу добавить ограничение в моем подзапросе.

Спасибо.

1 Ответ

0 голосов
/ 13 января 2019

В github есть проблема .

Был задан тот же вопрос:

Возможное быстрое решение взлома может быть следующим:

  • Добавьте нужный столбец select к столбцу "order by" в операторе выбора
  • , используйте MIN или MAX , чтобы объединить результаты впросто получите 1-й (чтобы получить тот же результат, что и LIMIT 1)

Этот подпункт:

$qb->addSelect("(SELECT LOWER(ats.assignee) from Entity\AssessmentTimelineStatus ats, Entity\AssessmentStudentTimeline ast "
        . "WHERE ast.assessmentTimelineStatus = ats.id AND ast.user = igsm.user AND ast.assessment = qp.id "
        . "ORDER BY ats.id DESC LIMIT 1) AS assignee");

будет записан как:

$qb->addSelect("(SELECT MAX(concat(ats.id, ' ', LOWER(ats.assignee))) from Entity\AssessmentTimelineStatus ats, Entity\AssessmentStudentTimeline ast "
        . "WHERE ast.assessmentTimelineStatus = ats.id AND ast.user = igsm.user AND ast.assessment = qp.id "
        . "ORDER BY ats.id DESC) AS assignee");

Когда вы получите значение «assignee», вы можете разделить его на 1-е значение одиночного пробела и получить значение «LOWER (ats.assignee)».

$result = explode(' ',$assignee, 2);

Использовать MAX, если ORDER BY равен DESC иMIN при ASC.

Это работает, потому что агрегатная функция MAX или MIN выбирает только самое высокое или самое низкое значение , которое может быть числом или строкой.

Ссылки

MAX / MIN документация mysql

взорваться до 1-го символа пробела

...