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).

Was it helpful?

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;        
}
Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top