2017-07-20 71 views
0

「無效使用組功能的」使用MySQL,我的數據庫看起來是這樣的:在MySQL

+-----------------------+--------------------+------+--------+ 
|  moviesInfo  |     |  |  | 
+-----------------------+--------------------+------+--------+ 
| title     | director   | year | oscars | 
+-----------------------+--------------------+------+--------+ 
| BoBoiBoy: The Movie | Nizam Razak  | 2016 | 0  | 
| Inception    | Christopher Nolan | 2010 | 4  | 
| Interstellar   | Christopher Nolan | 2014 | 1  | 
| Munna Bhai M.B.B.S. | Rajkumar Hirani | 2003 | 0  | 
| My Dear Brother  | Ertem Egilmez  | 1973 | 0  | 
| Rocky     | John G. Avildsen | 1976 | 3  | 
| The Nights of Cabiria | Federico Fellini | 1957 | 1  | 
| The Sixth Sense  | M. Night Shyamalan | 1999 | 6  | 
| Tokyo Story   | Yasujirô Ozu  | 1953 | 0  | 
| Yojimbo    | Akira Kurosawa  | 1961 | 1  | 
+-----------------------+--------------------+------+--------+ 


select director from moviesInfo 
where MAX(year) > 2000 and SUM(oscars) > 2 
group by director; 

通過上述查詢我試圖讓誰後來有一部電影在2000年,有更多的導演比2 oscars,但我得到一個錯誤

Invalid use of group function 

仍然是MySQL的新手我不完全理解這一點。

預期輸出將是

+-------------------+ 
|  director  | 
+-------------------+ 
| Christopher Nolan | 
+-------------------+ 

回答

3

GROUP BY aggregate functions不能WHERE子句中使用。他們應該停留在HAVING子句中,在GROUP BY之後,因爲它們在分組生成的值集上運行。

您的查詢應該是:

SELECT director 
FROM moviesInfo 
GROUP BY director 
HAVING MAX(year) > 2000 AND SUM(oscars) > 2 

更新

在OP的要求,這,大概,怎麼上面的SQL查詢被執行:

  1. GROUP BY條款告知服務器對匹配的行進行分組(所有行爲 ,因爲沒有WHERE子句可對其進行過濾)。所述組如下:

    +-----------------------+--------------------+------+--------+ 
    | title     | director   | year | oscars | 
    +-----------------------+--------------------+------+--------+ 
    | BoBoiBoy: The Movie | Nizam Razak  | 2016 | 0  | 
    +-----------------------+--------------------+------+--------+ 
    | Inception    | Christopher Nolan | 2010 | 4  | 
    | Interstellar   | Christopher Nolan | 2014 | 1  | 
    +-----------------------+--------------------+------+--------+ 
    | Munna Bhai M.B.B.S. | Rajkumar Hirani | 2003 | 0  | 
    +-----------------------+--------------------+------+--------+ 
    | My Dear Brother  | Ertem Egilmez  | 1973 | 0  | 
    +-----------------------+--------------------+------+--------+ 
    | Rocky     | John G. Avildsen | 1976 | 3  | 
    +-----------------------+--------------------+------+--------+ 
    | The Nights of Cabiria | Federico Fellini | 1957 | 1  | 
    +-----------------------+--------------------+------+--------+ 
    | The Sixth Sense  | M. Night Shyamalan | 1999 | 6  | 
    +-----------------------+--------------------+------+--------+ 
    | Tokyo Story   | Yasujirô Ozu  | 1953 | 0  | 
    +-----------------------+--------------------+------+--------+ 
    | Yojimbo    | Akira Kurosawa  | 1961 | 1  | 
    +-----------------------+--------------------+------+--------+ 
    
  2. HAVING的子句使得計算MAX(year)SUM(oscars)爲每個組。該數據現在看起來像:

    +-----------------------+--------------------+------+--------+-----------+-------------+ 
    | title     | director   | year | oscars | MAX(year) | SUM(oscars) | 
    +-----------------------+--------------------+------+--------+-----------+-------------+ 
    | BoBoiBoy: The Movie | Nizam Razak  | 2016 | 0  | 2016  | 0   | 
    +-----------------------+--------------------+------+--------+-----------+-------------+ 
    | Inception    | Christopher Nolan | 2010 | 4  | 2014  | 5   | 
    | Interstellar   | Christopher Nolan | 2014 | 1  |   |    | 
    +-----------------------+--------------------+------+--------+-----------+-------------+ 
    | Munna Bhai M.B.B.S. | Rajkumar Hirani | 2003 | 0  | 2003  | 0   | 
    +-----------------------+--------------------+------+--------+-----------+-------------+ 
    | My Dear Brother  | Ertem Egilmez  | 1973 | 0  | 1973  | 0   | 
    +-----------------------+--------------------+------+--------+-----------+-------------+ 
    | Rocky     | John G. Avildsen | 1976 | 3  | 1976  | 3   | 
    +-----------------------+--------------------+------+--------+-----------+-------------+ 
    | The Nights of Cabiria | Federico Fellini | 1957 | 1  | 1957  | 1   | 
    +-----------------------+--------------------+------+--------+-----------+-------------+ 
    | The Sixth Sense  | M. Night Shyamalan | 1999 | 6  | 1999  | 6   | 
    +-----------------------+--------------------+------+--------+-----------+-------------+ 
    | Tokyo Story   | Yasujirô Ozu  | 1953 | 0  | 1953  | 0   | 
    +-----------------------+--------------------+------+--------+-----------+-------------+ 
    | Yojimbo    | Akira Kurosawa  | 1961 | 1  | 1961  | 1   | 
    +-----------------------+--------------------+------+--------+-----------+-------------+ 
    
  3. 接下來,HAVING的條件進行評估和數據集的樣子:

    +-----------------------+--------------------+------+--------+-----------+-------------+ 
    | title     | director   | year | oscars | MAX(year) | SUM(oscars) | 
    +-----------------------+--------------------+------+--------+-----------+-------------+ 
    | Inception    | Christopher Nolan | 2010 | 4  | 2014  | 5   | 
    | Interstellar   | Christopher Nolan | 2014 | 1  |   |    | 
    +-----------------------+--------------------+------+--------+-----------+-------------+ 
    
  4. 現在SELECT子句用於生成結果集你期望。

請注意,上面的解釋是GROUP BY查詢背後的理論模型。在現實世界中,MySQL(和其他RDBMS)以不同的順序混合並運行上述步驟。它結合了WHEREHAVING子句(如果可能),一次處理一行,並嘗試儘可能多地過濾儘可能多的行,以便儘快完成處理。

備註

SELECT子句上的GROUP BY查詢can contain only expressions在於:

  1. 也存在於GROUP BY子句中;
    例如,director;
  2. GROUP BY aggregate functions;
    例如SUM(oscars),COUNT(*),AVG(year)等。沒有要求它們存在於其他條款中;
  3. 在功能上依賴於存在於GROUP BY子句中的列;例如,
    例如,如果GROUP BY子句包含表的PK列,那麼SELECT子句中允許該表的任何列,因爲組中存在的所有行將具有該表的所有列的相同值。

讓我們此言的列titleyearoscars不能成爲SELECT子句中,因爲不符合上述任何條件。將它們添加到SELECT子句中會生成無效的SQL。原因很明顯:第二組中有title有兩個不同的值。哪一個可以選擇?

在版本5.7.5之前,MySQL用於接受這種無效的SQL查詢,但保留其對return indeterminate results的權利。這意味着如果對不同計算機上的相同數據集執行查詢(或從備份中恢復數據之後),結果可能會更改。

從版本5.7.5開始,MySQL拒絕無效的GROUP BY查詢。

+0

謝謝,你能解釋一下'HAVING'子句的作用嗎? – Ludisposed

+0

@Ludisposed'HAVING'有點像'WHERE',只是它在形成的組上運行而不是每個記錄。他的HAVING條款是說一個導演的記錄組在2000年以後的一年中,它的奧斯卡總和超過了2個。 –

+0

優秀的消除,我感到很難過,我現在不能兩次投票。 – Ludisposed