2012-10-23 91 views
2

我有以下查询:MySQL错误子查询返回多个1行

SELECT 
    users.*, 
    classes.*, 
    evaluation.student_id, 
    evaluation.class_id, 
    evaluation.chapter_title, 
    (SELECT 
     `score` 
    FROM 
     `evaluation` 
    WHERE 
     `class_id` = 1 
    AND 
     `id` 
    IN 
     (SELECT 
      MAX(`id`) 
     FROM 
      `evaluation` 
     WHERE 
      `class_id` = 1 
     GROUP BY 
      `chapter_title`) 
    GROUP BY 
     `chapter_title`) 
    AS 
     `score`, 
    (SELECT 
     `total_score` 
     FROM 
     `evaluation` 
     WHERE 
     `class_id` = 1 
     AND 
     `id` 
     IN 
     (SELECT 
      MAX(`id`) 
     FROM 
      `evaluation` 
     WHERE 
      `class_id` = 1 
     GROUP BY 
      `chapter_title`) 
     GROUP BY 
     `chapter_title`) 
     AS 
     `total_score` 
     FROM 
     (`evaluation` 
     INNER JOIN 
     `users` 
     ON 
     evaluation.student_id=users.id) 
     INNER JOIN 
     `classes` 
     ON 
     evaluation.class_id=classes.id 
     WHERE 
     users.role='student' 
     AND 
     evaluation.class_id = 1 
     AND 
     evaluation.student_id = 8 

但是,当我在phpMyAdmin执行这个查询会显示一条错误消息说:

#1242 - Subquery returns more than 1 row 

哪些错误的请帮助。提前致谢。

我有这个表:

用户 enter image description here

enter image description here

评价 enter image description here

在评价表(最后一个图像)。我只想要回一个不同的chapter_title或者一个分组的chapter_title,它具有最高的id并且有一个学生_id为8.

我需要使用此查询...但会返回一个错误。

回答

1

您需要在所有子查询上使用LIMIT 1,以确保只返回一个值。

E.g.

select users.*, classes.*, evaluation.student_id, evaluation.class_id, evaluation.chapter_title, (
     select `score` 
     from `evaluation` 
     where `class_id` = 1 
      and `id` in (
       select MAX(`id`) 
       from `evaluation` 
       where `class_id` = 1 
       group by `chapter_title` 
       ) 
     group by `chapter_title` 
     limit 1 
     ) as `score`, (
     select `total_score` 
     from `evaluation` 
     where `class_id` = 1 
      and `id` in (
       select MAX(`id`) 
       from `evaluation` 
       where `class_id` = 1 
       group by `chapter_title` 
       ) 
     group by `chapter_title` 
     limit 1 
     ) as `total_score` 
from (
    `evaluation` inner join `users` on evaluation.student_id = users.id 
    ) 
inner join `classes` on evaluation.class_id = classes.id 
where users.role = 'student' 
    and evaluation.class_id = 1 
    and evaluation.student_id = 8 
+0

我会试试看 –

+0

我只想最高的ID返回一个不同的章节标题。但是这个查询返回所有的章节标题 –

+0

根据你的问题标题,我解决了你的查询中的错误。至于业务逻辑,如果您遇到问题,请发布一个新问题。 – RedFilter

0

最有可能您的SELECT scores子查询(第一个)将返回多行。它是IN()子句中未使用的唯一一个,其结果作为父查询中的字段返回。由于它“返回”到一个字段,它必须导致一个值+单行结果集。

1

这里是corrected fiddle

SELECT 
    users.*, 
    classes.*, 
    evaluation.student_id, 
    evaluation.class_id, 
    evaluation.chapter_title, 
    evaluation.score, 
    evaluation.total_score 
FROM 
    evaluation 
INNER JOIN users 
ON 
    evaluation.student_id=users.id 
    INNER JOIN 
    classes 
    ON 
    evaluation.class_id=classes.id 
    WHERE 
    users.role='student' 
    AND 
    evaluation.class_id = 1 
    AND 
    evaluation.student_id = 8 
AND 
EXISTS 
    (SELECT 
     * 
    FROM 
     evaluation 
    WHERE 
     class_id = 1 
    HAVING MAX(id) = evaluation.id) 
GROUP BY 
    chapter_title 

的主要变化:

  1. 相反的IN,使用EXISTS(应该会更快,因为它不会需要返回它的所有子行);是没有必要

  2. 一些子查询。

2

的问题是,无论你的查询返回多个记录:

SELECT `score` 
    FROM `evaluation` 
    WHERE `class_id` = 1 
     AND `id` IN (SELECT MAX(`id`) 
        FROM `evaluation` 
        WHERE `class_id` = 1 
        GROUP BY `chapter_title`) 
    GROUP BY `chapter_title`; 

SELECT `total_score` 
     FROM `evaluation` 
     WHERE `class_id` = 1 
     AND `id` IN (SELECT MAX(`id`) 
        FROM `evaluation` 
        WHERE `class_id` = 1 
        GROUP BY `chapter_title`) 
     GROUP BY`chapter_title`; 

SQL Fiddle with demo

我改变您的查询小幅以下几点:

SELECT u.*, 
    c.*, 
    e.student_id, 
    e.class_id, 
    e.chapter_title, 
    (SELECT `score` 
    FROM `evaluation` e1 
    WHERE `class_id` = 1 
     AND e.id = e1.id 
     AND `id` IN (SELECT MAX(`id`) 
        FROM `evaluation` 
        WHERE `class_id` = 1 
        GROUP BY `chapter_title`) 
    GROUP BY `chapter_title`) AS`score`, 
    (SELECT `total_score` 
     FROM `evaluation` e1 
     WHERE `class_id` = 1 
     AND e.id = e1.id 
     AND `id` IN (SELECT MAX(`id`) 
        FROM `evaluation` 
        WHERE `class_id` = 1 
        GROUP BY `chapter_title`) 
     GROUP BY`chapter_title`) AS `total_score` 
FROM `evaluation` e 
INNER JOIN `users` u 
    ON e.student_id=u.id 
INNER JOIN `classes` c 
    ON e.class_id=c.id 
WHERE u.role='student' 
    AND e.class_id = 1 
    AND e.student_id = 8 

SQL Fiddle with demo