"子查询的解决方案返回超过1行"错误

时间:2015-01-27 13:17:22

标签: mysql

我有一个返回多行的查询,另一个查询在其中我想将条件设置为这些多行中的值之一,所以基本上我希望子查询看起来像这样:

select * 
from table
where id= (multiple row query);

multiple row query返回多行。因此,如果这些行的值是1,2,3,那么我想将id设置为1或2或3。

5 个答案:

答案 0 :(得分:85)

当子查询只返回1个值时,可以使用

=

当子查询返回的值超过1时,您必须使用IN

select * 
from table
where id IN (multiple row query);

例如:

SELECT *
FROM Students
WHERE Marks = (SELECT MAX(Marks) FROM Students)   --Subquery returns only 1 value

SELECT *
FROM Students
WHERE Marks IN 
      (SELECT Marks 
       FROM Students 
       ORDER BY Marks DESC
       LIMIT 10)                       --Subquery returns 10 values

答案 1 :(得分:7)

您可以使用in()

select * 
from table
where id in (multiple row query)

或使用联接:

select distinct t.* 
from source_of_id_table s
join table t on t.id = s.t_id
where <conditions for source_of_id_table>

连接永远不是性能的最差选择,并且根据您使用的确切情况和数据库,可以提供更好的性能。

答案 2 :(得分:0)

在您的MAX中使用SELECT返回值。.示例

INSERT INTO school_year_studentid (student_id,syr_id) VALUES
((SELECT MAX(student_id) FROM student), (SELECT MAX(syr_id) FROM school_year))

代替

INSERT INTO school_year_studentid (student_id,syr_id) VALUES
((SELECT (student_id) FROM student), (SELECT (syr_id) FROM school_year))

在没有MAX的情况下尝试使用它会产生多个值

答案 3 :(得分:0)

当出现错误“子查询返回多于一行”时,数据库实际上告诉您存在无法解析的循环引用。有点像使用电子表格,说单元格A1 = B1,然后说B1 = A1。此错误通常与需要具有双重嵌套子查询的情况有关。我建议您查找一个名为“ 交叉表查询 ”的东西,这是通常需要解决的问题的查询类型。它基本上是嵌套在子查询中的外部联接(左或右),反之亦然。也可以通过双重联接(也被认为是 跨表查询 的一种)解决此问题,如下所示:

CREATE DEFINER=`root`@`localhost` PROCEDURE `SP_GET_VEHICLES_IN`(
    IN P_email VARCHAR(150),
    IN P_credentials VARCHAR(150)
)
BEGIN
    DECLARE V_user_id INT(11);
    SET V_user_id = (SELECT user_id FROM users WHERE email = P_email AND credentials = P_credentials LIMIT 1);
    SELECT vehicles_in.vehicle_id, vehicles_in.make_id, vehicles_in.model_id, vehicles_in.model_year,
    vehicles_in.registration, vehicles_in.date_taken, make.make_label, model.model_label
    FROM make
    LEFT OUTER JOIN vehicles_in ON vehicles_in.make_id = make.make_id
    LEFT OUTER JOIN model ON model.make_id = make.make_id AND vehicles_in.model_id = model.model_id
    WHERE vehicles_in.user_id = V_user_id;
END

在上面的代码中,请注意在SELECT子句中有三个表,并且这三个表显示在FROM子句之后和两个LEFT OUTER JOIN子句之后,这三个表在FROM和LEFT OUTER JOIN之间必须是不同的子句在语法上是正确的。

值得注意的是,作为开发人员,这是一个非常重要的结构,尤其是在编写定期报告查询时,它可能是任何复杂的交叉引用的最重要技能,因此所有开发人员都应研究这些结构( 交叉表 双重加入 )。

我必须警告的另一件事是:如果要使用交叉表作为工作系统的一部分,而不仅仅是定期报告,则必须检查记录计数并重新配置连接条件,直到出现最小记录为止返回,否则大型表和交叉表会使服务器陷入瘫痪。 希望这会有所帮助。

答案 4 :(得分:0)

添加我的答案,因为它阐述了您可以从子查询的表中选择多个列的想法。

这里我需要最近铸造的 cote 及其相关信息。

我首先尝试简单地选择 max(votedate) 以及投票、itemid、userid 等,但是虽然查询将返回最大投票日期,但它也会返回其他信息的随机行。在一堆 1 和 0 中很难看到。

效果很好:

$query = "  
    SELECT t1.itemid, t1.itemtext, t2.vote, t2.votedate, t2.userid 
    FROM
        (
        SELECT itemid, itemtext FROM oc_item ) t1
    LEFT JOIN 
        (
        SELECT vote, votedate, itemid,userid FROM oc_votes
        WHERE votedate IN 
        (select max(votedate) FROM oc_votes group by itemid)
        AND userid=:userid) t2
    ON (t1.itemid = t2.itemid)
    order by itemid ASC
";

WHERE 子句中的子查询 WHERE votedate IN (select max(votedate) FROM oc_votes group by itemid) 返回一条记录——投票日期最大的记录。