2016-12-06 26 views
3

我有這個SQL查詢,它給我一個不完整的結果(一半結果)。我想要從學生表中找到同一班級的所有學生信息,然後按班級分組。SQL GROUP BY和HAVING無法正常工作

這些查詢代碼:

SELECT first_name, last_name, username 
FROM students 
GROUP BY class   
HAVING class IN(SS3); 

SELECT first_name, last_name, class 
FROM students 
GROUP BY class 
HAVING class = 'JSS1'; 

SELECT user_id, first_name, last_name, class, COUNT(*) AS total_students 
FROM students 
GROUP BY class 
HAVING class IN ('JSS1') 

最後一個查詢還顯示僅僅只有一個信息,這是第一個「jss1」班的學生在表名,但這次顯示,有17在jss1中的學生

如何操作查詢以顯示同一班級中所有學生的姓名?

這是表結構:

CREATE TABLE IF NOT EXISTS `students` (
    `user_id` int(11) NOT NULL AUTO_INCREMENT, 
    `class` varchar(10) NOT NULL, 
    `first_name` varchar(30) NOT NULL, 
    `last_name` varchar(50) NOT NULL, 
    `username` varchar(20) NOT NULL, 
    PRIMARY KEY (`user_id`) 
) 
+1

一般的GROUP BY規則說:如果指定了GROUP BY子句,SELECT列表中的每個列引用必須標識一個分組列或者是一個set函數的參數! – jarlh

+1

如果你想只顯示班級學生只是使用條件,而不使用GROUP BY –

+0

好的......我會這樣做,但我只是認爲它會更好地使用GROUP BY和HAVING – manprogram

回答

0

,如果你需要給定類的所有學生,where子句

SELECT first_name, last_name, class 
FROM students 
WHERE class = 'JSS1'; 
+0

我會這樣做,但不能使用GROUP BY? – manprogram

0

你寫的查詢,並沒有什麼意義,爲什麼不使用,並不會解析我所知道的任何其他DBMS。 MySQL extends the standard SQL use of GROUP BY so that the select list can refer to nonaggregated columns not named in the GROUP BY clause.,既可以是祝福也可以是詛咒。

協助,請考慮下面的示例數據現在

UserID  Class  First_name 
------------------------------------ 
1   A   Test 1 
2   A   Test 2 
3   B   Test 3 
4   B   Test 4 
5   C   Test 5 

,在第一個查詢(調整以符合上述數據)

SELECT first_name 
FROM students 
GROUP BY class   
HAVING class IN('A'); 

我們首先需要思考的邏輯順序上述操作:

1. FROM 
2. WHERE 
3. GROUP BY 
4. HAVING 
5. SELECT 

所以看的第一件事是,犯罪集團CE class是要返回每個組一行分組列,所以你會:

class first_name 
------------------ 
A  ??? 
B  ??? 
C  ??? 

having子句現在規定,它必須是一個,留下:

class first_name 
------------------ 
A  ??? 

現在,這是大多數DBMS失敗的原因,此時您需要SELECT first_name,但是您有兩個可用的值(「測試1」和「測試2」),但只有一行要填充,並且已經給出引擎沒有關於哪個其中一個選擇。該文檔指出引擎可以自由選擇任何可用值,並且該順序不會影響該值,因此根據執行計劃的不同,對於相同的查詢可能會有所不同。

雖然你不確定GROUP BY,但我建議你啓用ONLY_FULL_GROUP_BY

所以這就是爲什麼你只得到一排,而不是所有的學生。答案是如何讓所有的學生是一個相當簡單的,只需使用WHERE

SELECT first_name, last_name, username 
FROM Students 
WHERE Class IN ('JSS1'); 

如果你想每類一列的格式相同,但列出的所有學生,那麼你可能想GROUP_CONCAT

SELECT class, GROUP_CONCAT(CONCAT(First_name, ' ', last_name)) AS Students 
FROM Students 
GROUP BY class; 

最後,你應該只有USING具有聚合函數。這方面的一個例子可能是試圖找到個教學班,2名學生:

SELECT Class 
FROM Students 
GROUP BY Class 
HAVING COUNT(*) = 2; 
1

GROUP BY條款,當你想組已申請有關的聚集函數的一些信息(如上次查詢要知道COUNT) 。

所以,當你有一個聚合函數,如果你想用它來展示,標量場,這些必須放在GROUP BY條款。

HAVING子句是用來申請彙總值的條件(例如,我想知道用COUNT> 1的所有行),我會寫:HAVING COUNT() > 1,因此所有查詢必須使用WHERE條款

您的疑問:

WRONG

SELECT first_name, last_name, username 
FROM students 
GROUP BY class   
HAVING class IN(SS3); 

BECOMES

SELECT first_name, last_name, username 
FROM students   
WHERE class IN (SS3); 

WRONG

SELECT first_name, last_name, class 
FROM students 
GROUP BY class 
HAVING class = 'JSS1'; 

BECOMES

SELECT first_name, last_name, class 
FROM students 
WHERE class = 'JSS1'; 

WRONG

SELECT user_id, first_name, last_name, class, COUNT(*) AS total_students 
FROM students 
GROUP BY class 
HAVING class IN ('JSS1') 

BECOMES

SELECT user_id, first_name, last_name, class, COUNT(*) AS total_students 
FROM students 
WHERE class IN ('JSS1') 
GROUP BY class, user_id, first_name, last_name 
0

如果要列出學生在給定的類來完成此:

SELECT first_name, last_name, class 
FROM students 
WHERE class = 'JSS1'; 

查詢列出每個類

SELECT class, count(user_id) 
FROM students 
GROUP BY class; 

你看這些學生的數量兩個查詢解決了不同的目的。 group by子句用於將相關數據組合在一起,偏離課程時應該列出您正在選擇的group by中提及的所有列。

你可能會使用GROUP BY以及學生在特定類的列表,您的查詢會是這樣的:

SELECT first_name, last_name, class 
FROM students 
GROUP BY first_name, last_name, class 
HAVING class = 'JSS1'; 

注意,在上面查詢中使用group by是不必要的,你可以實現輕鬆使用where結果子句在第一個查詢中完成。