Zend Framework subquery select. Cardinality violation: Operand should contain 1 column(s)

StackOverflow https://stackoverflow.com/questions/23431611

سؤال

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

هل كانت مفيدة؟

المحلول

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;        
}
مرخصة بموجب: CC-BY-SA مع الإسناد
لا تنتمي إلى StackOverflow
scroll top