2011-10-23 57 views
1

我得到一個錯誤:#1242 - 當我運行這個sql時,子查詢返回多於一行。錯誤:#1242 - 子查詢返回多於一行

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; 
+0

可能重複[Mysql :: Error:子查詢返回多於1行:](http://stackoverflow.com/questions/637613/mysqlerror-subquery-returns-more-than-1-row),[MySQL :子查詢返回多個行](http://stackoverflow.com/questions/778239/mysql-subquery-returns-more-than-one-row),[爲什麼MySQL給「子查詢返回多個行」錯誤?](http://stackoverflow.com/questions/863665/why-does-mysql-give-subquery-returns-more-than-1-row-error)和[幫助子查詢!返回多於1行](http://stackoverflow.com/questions/2419094/help-with-subquery-returns-more-than-1-row)。 –

+0

@Ken White:使用相同的標記/錯誤消息並不意味着這些是重複的。 –

+0

第二個問題是,包括與「COUNT」有關的問題。四個中的三個解釋錯誤意味着什麼,這應該導致海報發現自己。 (就像讀到實際的錯誤信息,看着查詢並思考「嗯,有兩種可能性,因爲有兩個子查詢,也許我應該單獨運行它們來查看它們是否返回多行,然後我可以嘗試「 –

回答

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 
4

問題是您的子查詢返回多個值 - IE:

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

...將爲每個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 
+0

我認爲你的'SUM'有點冒險;正如a1ex07所暗示的那樣,使用'COUNT'更清楚。 – ruakh

+0

對不起,但我敢肯定你在測試中犯了一個錯誤。 'COUNT'計數所有非'NULL'值;在你的附錄中,你有一個'ELSE 0',這是錯誤的。 (它需要是'ELSE NULL',或者只是省略。)在你的評論中,你省略了'ELSE 0',但我敢打賭這不是你實際測試的。 – ruakh

+1

@ruakh:謝謝你接受,更新。但是,我不明白'SUM'是如何明確地演示如何進行計算的。顯然,COUNT'要求用戶知道'NULL'處理並適當地構建查詢 - 這使得COUNT比使用SUM更加「黑客」。 –

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 +旋轉(主要是出於學習的目的,這是一個更長的查詢):

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 
1

這是因爲你的子查詢(位於括號內的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所說的,如果你不想使用子查詢,你實際上不需要使用子查詢。

+0

+1:我打算演示相關子查詢但忘記了。 –

相關問題