Question

That is my query:

$subquery = "(SELECT `id`, `mark`, `date`, `session` FROM `student_marks` WHERE `student_id` = '" . $studentId . "')";

    $q = $this->select()
        ->distinct()
        ->setIntegrityCheck(false)
        ->from($this->_name, array('name AS subjectName', 'student_marks' => new Zend_Db_Expr($subquery)))
        ->joinLeft('class_teachers', 'class_teachers.subject_id = subjects.id', '')
        ->joinLeft('teachers', 'teachers.id = class_teachers.teacher_id', array('teachers.name AS teacherName', 'teachers.family AS teacherFamily'))
        ->joinLeft('student_session_marks', 'student_session_marks.subject_id = subjects.id', array('student_session_marks.id AS sessionMarkId', 'student_session_marks.mark AS sessionMarkName', 'student_session_marks.session AS sessionMarkSession'))
        ->where('student_session_marks.student_id = ?', $studentId);

Print of query:

SELECT DISTINCT `subjects`.`name` AS `subjectName`, 
    (SELECT `id`, `mark`, `date`, `session` FROM `student_marks` WHERE `student_id` = '6') AS `student_marks`, 
    `teachers`.`name` AS `teacherName`, `teachers`.`family` AS `teacherFamily`, `student_session_marks`.`id` AS `sessionMarkId`, 
    `student_session_marks`.`mark` AS `sessionMarkName`, `student_session_marks`.`session` AS `sessionMarkSession` 
FROM `subjects`
LEFT JOIN `class_teachers` ON class_teachers.subject_id = subjects.id
LEFT JOIN `teachers` ON teachers.id = class_teachers.teacher_id
LEFT JOIN `student_session_marks` ON student_session_marks.subject_id = subjects.id 
WHERE (student_session_marks.student_id = '6')

When I remove subquery, my query work successfully, otherwise have this error:

SQLSTATE[21000]: Cardinality violation: 1241 Operand should contain 1 column(s).

Était-ce utile?

La solution

this is operator error... when you are doing inner query for a select it MUST return only 1 column with 1 record, not a multi-row/multi-column dataset.

As with any task there are few ways of solving the task and to get best solution need to clearly understand what you are trying to do...

Based on your code I think below is what you are looking for:

public function getStudentSubjectMarks($studentId)
{
    // cast your input (assume it's numeric...
    $studentId = (int) $studentId;

    //
    $db = $this->getAdapter();
    $q = $db->select()
            ->distinct()
            ->from($this->_name, array('name AS subjectName'))
            ->joinLeft('class_teachers', 'class_teachers.subject_id = subjects.id')
            ->joinLeft('teachers', 'teachers.id = class_teachers.teacher_id', array(
                'teachers.name AS teacherName',
                'teachers.family AS teacherFamily',
            ))
            ->joinLeft('student_session_marks', 'student_session_marks.subject_id = subjects.id', array(
                'student_session_marks.id AS sessionMarkId',
                'student_session_marks.mark AS sessionMarkName',
                'student_session_marks.session AS sessionMarkSession'
            ))
            ->where('student_session_marks.student_id = ?', $studentId);

    $data = array();
    foreach ($db->fetchAll($q) as $record) {
        $queryMarks = $db->select()
                ->from('student_marks', array('id', 'mark', 'date', 'session'))
                ->where('student_id = ?', $studentId);

        //  add marks to the student record
        $record['student_marks'] = $db->fetchAll($queryMarks);

        //  add to main return array
        $data[] = $record;
    }

    // more logic...

    return $data;        
}
Licencié sous: CC-BY-SA avec attribution
Non affilié à StackOverflow
scroll top