error : #1242 - Subquery returns more than 1 row

前端 未结 4 609
夕颜
夕颜 2020-12-11 11:39

I got an error: #1242 - Subquery returns more than 1 row when i run this sql.

CREATE VIEW test 
AS 
  SELECT cc_name, 
         COUNT() AS total, 
         (         


        
相关标签:
4条回答
  • 2020-12-11 11:50
    SELECT COUNT() 
              FROM   bed 
              WHERE  respatient_id > 0 
              GROUP  BY cc_name
    

    You need to remove the group-by in the sub query, so possibly something like

    SELECT COUNT(*) 
              FROM   bed 
              WHERE  respatient_id > 0 
    

    or possibly -- depending on what your application logic is....

    SELECT COUNT(*) from (
              select count(*),cc_name FROM   bed 
              WHERE  respatient_id > 0 
              GROUP  BY cc_name) filterview
    
    0 讨论(0)
  • 2020-12-11 11:56

    The problem is that your subselects are returning more than one value - IE:

    SELECT ...
           (SELECT COUNT(*) 
              FROM bed 
             WHERE respatient_id IS NULL 
          GROUP BY cc_name) AS free_beds,
           ...
    

    ...will return a row for each cc_name, but SQL doesn't support compacting the resultset for the subselect - hence the error.

    Don't need the subselects, this can be done using a single pass over the table using:

      SELECT b.cc_name, 
             COUNT(*) AS total, 
             SUM(CASE 
                   WHEN b.respatient_id > 0 THEN 1 
                   ELSE 0 
                 END) AS occupied_beds, 
             SUM(CASE 
                   WHEN b.respatient_id IS NULL THEN 1 
                   ELSE 0 
                 END) AS free_beds 
        FROM bed b
    GROUP BY b.cc_name
    
    0 讨论(0)
  • 2020-12-11 11:59

    This is because your subqueries (the SELECT bits that are inside parentheses) are returning multiple rows for each outer row. The problem is with the GROUP BY; if you want to use subqueries for this, then you need to correlate them to the outer query, by specifying that they refer to the same cc_name as the outer query:

    CREATE VIEW test 
    AS 
      SELECT cc_name, 
             COUNT()             AS total, 
             (SELECT COUNT() 
              FROM   bed 
              WHERE  cc_name = bed_outer.cc_name
              AND    respatient_id > 0) AS occupied_beds, 
             (SELECT COUNT(*) 
              FROM   bed 
              WHERE  cc_name = bed_outer.cc_name
              WHERE  respatient_id IS NULL) AS free_beds 
      FROM   bed AS bed_outer
      GROUP  BY cc_name;
    

    (See http://en.wikipedia.org/wiki/Correlated_subquery for information about correlated subqueries.)

    But, as OMG Ponies and a1ex07 say, you don't actually need to use subqueries for this if you don't want to.

    0 讨论(0)
  • 2020-12-11 12:13

    Your subqueries return more than 1 row. I think you you need something like :

     SELECT COUNT(*) AS total, 
     COUNT(CASE WHEN respatient_id > 0 THEN 1 END) AS occupied_beds,
     COUNT(CASE WHEN respatient_id IS NULL THEN 1 END) AS free_beds          
     FROM   bed 
     GROUP  BY cc_name
    

    You can also try to use WITH ROLLUP + pivoting (mostly for learning purposes, it's a much longer query ) :

    SELECT cc_name, 
    MAX(CASE 
     WHEN num_1 = 1 THEN tot_num END) AS free_beds,
    
    MAX(CASE 
     WHEN num_1 = 2 THEN tot_num END) AS occupied_beds,
    
    MAX(CASE 
     WHEN num_1 = IS NULL THEN tot_num END) AS total
    
    FROM
    (SELECT cc_name, CASE 
    WHEN respatient_id > 0 THEN 1
    WHEN respatient_id IS NULL THEN 2
    ELSE 3 END as num_1,
    COUNT(*) as tot_num
    FROM  bed
    WHERE 
    CASE 
    WHEN respatient_id > 0 THEN 1
    WHEN respatient_id IS NULL THEN 2
    ELSE 3 END != 3
    GROUP BY cc_name,
    num_1 WITH ROLLUP)A
    GROUP BY cc_name
    
    0 讨论(0)
提交回复
热议问题