SELECT 列如何不在 GROUP BY 子句中列出
查詢:
select year,sum(mark),sum(maxmark) from table1 group by parameterno
產生一條錯誤消息:
列 ’table1.year’ 在選擇列表中無效,因為它不包含在聚合函式或 GROUP BY 子句中。
如果未將欄位包含在分組依據列表中,則無法跨欄位選擇聚合。
如果你想要每年的總數,你應該寫
SELECT year,sum(mark),sum(maxmark) FROM table1 GROUP BY year
如果你想要每個參數的總數,它應該是
SELECT parameterno,sum(mark),sum(maxmark) FROM table1 GROUP BY parameterno
從錯誤消息中我猜你正在使用 SQL Server 所以看看文件
我不清楚你在問什麼,但我相信這
GROUP BY
是 中最容易被誤解的概念之一SQL
,所以無論如何我都會添加這個答案。它可能會或可能不會有助於理解這個概念GROUP BY
。假設我們有一個像這樣的表:CREATE TABLE T ( YEAR INT NOT NULL , PARAMETERNO INT NOT NULL , MARK INT NOT NULL , PRIMARY KEY (YEAR, PARAMETERNO) ); INSERT INTO T ( YEAR, PARAMETERNO, MARK ) VALUES (2014,1,10),(2014,2,20),(2015,1,15),(2015,2,25);
什麼會:
SELECT YEAR, SUM(MARK) FROM T GROUP BY PARAMETERNO
意思是?按 PARAMETERNO 分組意味著我們有兩個組
1 2014 10 2015 20 2 2014 15 2015 25
我們應用了聚合函式 SUM,但是 YEAR 是如何發揮作用的呢?這可能意味著:
2014 30 -- 10+20 in group 1 2015 30 2014 40 -- 15+25 in group 2 2015 40
但這幾乎不是一個有用的結果?另一種可能性是從每組中隨機選擇一行,例如:
2014 30 -- 10+20 in group 1 2015 40 -- 15+25 in group 2
結果是不可預測的,對於相同的數據/查詢,您可能會得到不同的結果。
SQL92 要求 中的所有列
SELECT CLAUSE
都是 的一部分GROUP BY CLAUSE
,所以如果我們想要:SELECT YEAR, SUM(MARK) FROM T
我們必須至少將 YEAR 添加到
GROUP BY
:SELECT YEAR, SUM(MARK) FROM T GROUP BY YEAR
(可以添加其他列,但不是很常見)。結果:
2014 25 -- 10+15 in group 2014 2015 45 -- 20+25 in group 2015
SQL99 放寬了這一限制,並要求
SELECT
子句中的所有列在功能上由GROUP BY
子句確定(不是數據本身,而是聲明的約束)。在一個表的簡單情況下,這意味著如果GROUP BY
子句唯一標識一行,我們可以將我們想要的任何列添加到SELECT
子句中。例子:CREATE TABLE T ( YEAR INT NOT NULL , PARAMETERNO INT NOT NULL , MARK INT NOT NULL , PRIMARY KEY (YEAR) ); INSERT INTO T ( YEAR, PARAMETERNO, MARK ) VALUES (2014,1,10),(2015,2,20),(2016,1,15),(2017,2,25);
現在,因為
PARAMETERNO
在功能上由如下YEAR
查詢決定:SELECT YEAR, PARAMETERNO, SUM(MARK) FROM T GROUP BY YEAR
將是有效的。AFAIK 知道最新版本,
PostgreSQL
並且MySQL
是唯一實現 SQL99 版本的GROUP BY
.對於那些沒有實現 SQL99 版本的 DBMS 的一個技巧是對這些列應用聚合:
SELECT YEAR, MAX(PARAMETERNO), SUM(MARK) FROM T GROUP BY YEAR
由於每年只有一個 PARAMETERNO,因此結果是相同的。
MySQL 歷史上允許您違反 SQL92 和 SQL99
GROUP BY
規則,除非您在 @@sql_mode 中指定 ONLY_FULL_GROUP_BY。這可能會導致不確定的結果,並且多年來在諸如此類的論壇中引起了很多混亂。我個人總是將@@sql_mode 設置為 ONLY_FULL_GROUP_BY 當使用比最新版本更舊的 MySQL 時(我沒有嘗試過)。