2

我收到一个错误:#1242 - 当我运行这个 sql 时,子查询返回超过 1 行。

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

4 回答 4

4

问题是您的子选择返回多个值 - IE:

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

...将为 each 返回一行cc_name,但 SQL 不支持压缩子选择的结果集 - 因此出现错误。

不需要子选择,这可以使用表上的单遍来完成,使用:

  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
于 2011-10-23T16:05:54.140 回答
4

这是因为您的子查询(SELECT括号内的位)为每个外行返回多行。问题出在GROUP BY; 如果要为此使用子查询,则需要将它们与外部查询相关联,方法是指定它们与外部查询引用相同cc_name

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;

(有关相关子查询的信息,请参见http://en.wikipedia.org/wiki/Correlated_subquery。)

但是,正如 OMG Ponies 和 a1ex07 所说,如果您不想这样做,您实际上不需要为此使用子查询。

于 2011-10-23T16:11:26.207 回答
1

您的子查询返回超过 1 行。我认为你需要类似的东西:

 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

您也可以尝试使用WITH ROLLUP+ pivoting (主要用于学习目的,这是一个更长的查询):

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
于 2011-10-23T16:06:14.577 回答
0
SELECT COUNT() 
          FROM   bed 
          WHERE  respatient_id > 0 
          GROUP  BY cc_name

您需要在子查询中删除分组依据,所以可能类似于

SELECT COUNT(*) 
          FROM   bed 
          WHERE  respatient_id > 0 

或者可能 - 取决于您的应用程序逻辑是什么......

SELECT COUNT(*) from (
          select count(*),cc_name FROM   bed 
          WHERE  respatient_id > 0 
          GROUP  BY cc_name) filterview
于 2011-10-23T16:02:35.103 回答