Solution to “subquery returns more than 1 row” error

前端 未结 4 1689
囚心锁ツ
囚心锁ツ 2020-11-27 02:40

I have one query that returns multiple rows, and another query in which I want to set criteria to be either one of values from those multiple rows , so basicly I want the su

相关标签:
4条回答
  • 2020-11-27 03:22

    use MAX in your SELECT to return on value.. EXAMPLE

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

    instead of

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

    try it without MAX it will more than one value

    0 讨论(0)
  • 2020-11-27 03:27

    You can use in():

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

    or use a join:

    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>
    

    The join is never a worse choice for performance, and depending on the exact situation and the database you're using, can give much better performance.

    0 讨论(0)
  • 2020-11-27 03:30

    When one gets the error 'sub-query returns more than 1 row', the database is actually telling you that there is an unresolvable circular reference. It's a bit like using a spreadsheet and saying cell A1 = B1 and then saying B1 = A1. This error is typically associated with a scenario where one needs to have a double nested sub-query. I would recommend you look up a thing called a 'cross-tab query' this is the type of query one normally needs to solve this problem. It's basically an outer join (left or right) nested inside a sub-query or visa versa. One can also solve this problem with a double join (also considered to be a type of cross-tab query) such as below:

    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
    

    In the code above notice that there are three tables in amongst the SELECT clause and these three tables show up after the FROM clause and after the two LEFT OUTER JOIN clauses, these three tables must be distinct amongst the FROM and LEFT OUTER JOIN clauses to be syntactically correct.

    It is noteworthy that this is a very important construct to know as a developer especially if you're writing periodical report queries and it's probably the most important skill for any complex cross referencing, so all developers should study these constructs (cross-tab and double join).

    Another thing I must warn about is: If you are going to use a cross-tab as a part of a working system and not just a periodical report, you must check the record count and reconfigure the join conditions until the minimum records are returned, otherwise large tables and cross-tabs can grind your server to a halt. Hope this helps.

    0 讨论(0)
  • 2020-11-27 03:33

    = can be used when the subquery returns only 1 value.

    When subquery returns more than 1 value, you will have to use IN:

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

    For example:

    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
    
    0 讨论(0)
提交回复
热议问题