2012-10-23 87 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