Group-By

SELECT 列如何不在 GROUP BY 子句中列出

  • May 1, 2021

查詢:

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 和 SQL99GROUP BY規則,除非您在 @@sql_mode 中指定 ONLY_FULL_GROUP_BY。這可能會導致不確定的結果,並且多年來在諸如此類的論壇中引起了很多混亂。我個人總是將@@sql_mode 設置為 ONLY_FULL_GROUP_BY 當使用比最新版本更舊的 MySQL 時(我沒有嘗試過)。

引用自:https://dba.stackexchange.com/questions/141594