面試官:GROUP BY和DISTINCT有什么區(qū)別?
在 MySQL 中,GROUP BY 和 DISTINCT 都是用來(lái)處理查詢結(jié)果中的重復(fù)數(shù)據(jù),并且在官方的描述文檔中也可以看出:在大多數(shù)情況下 DISTINCT 是特殊的 GROUP BY,如下圖所示:
官方文檔地址:https://dev.mysql.com/doc/refman/8.0/en/distinct-optimization.html
但二者還是有一些細(xì)微的不同,接下來(lái)一起來(lái)看。
1.DISTINCT 介紹
- 用途:DISTINCT 用于從查詢結(jié)果中去除重復(fù)的行,確保返回的結(jié)果集中每一行都是唯一的。
- 語(yǔ)法:通常用于 SELECT 語(yǔ)句中,緊跟在 SELECT 關(guān)鍵字之后。例如以下 SQL:
SELECT DISTINCT column1, column2 FROM table_name;
- 工作機(jī)制:DISTINCT 會(huì)對(duì)整個(gè)結(jié)果集進(jìn)行去重,即只要結(jié)果集中的某一行與另一行完全相同,就會(huì)被去除。
2.GROUP BY 介紹
- 用途:GROUP BY 主要用于對(duì)結(jié)果集按照一個(gè)或多個(gè)列進(jìn)行分組,通常與聚合函數(shù)(如 COUNT, SUM, AVG, MAX, MIN 等)一起使用,以便對(duì)每個(gè)組進(jìn)行統(tǒng)計(jì)。
- 語(yǔ)法:GROUP BY 通常跟在 FROM 或 WHERE 子句之后,在 SELECT 語(yǔ)句的末尾部分。例如以下 SQL:
SELECT column1, COUNT(*) FROM table_name GROUP BY column1;
- 工作機(jī)制:GROUP BY 將數(shù)據(jù)按指定的列進(jìn)行分組,每個(gè)組返回一行數(shù)據(jù)。
3.舉例說(shuō)明
(1)使用 DISTINCT
假設(shè)有一個(gè)表 students,包含以下數(shù)據(jù):
id | name | age |
1 | Alice | 20 |
2 | Bob | 22 |
3 | Alice | 20 |
使用 DISTINCT 去除重復(fù)行:
SELECT DISTINCT name, age FROM students;
結(jié)果:
name | age |
Alice | 20 |
Bob | 22 |
(2)使用 GROUP BY
假設(shè)還是上面的表 students,我們想要統(tǒng)計(jì)每個(gè)學(xué)生的數(shù)量:
SELECT name, COUNT(*) AS count FROM students GROUP BY name;
結(jié)果:
name | count |
Alice | 2 |
Bob | 1 |
4.主要區(qū)別
- 功能不同:DISTINCT 用于去除重復(fù)行,而 GROUP BY 用于對(duì)結(jié)果集進(jìn)行分組,通常與聚合函數(shù)一起使用。
- 返回結(jié)果不同:DISTINCT 返回去重后的結(jié)果集,查詢結(jié)果集中只能包含去重的列信息,有其他列信息會(huì)報(bào)錯(cuò);GROUP BY 返回按指定列分組后的結(jié)果集,可以展示多列信息,并可以包含聚合函數(shù)的計(jì)算結(jié)果。
- 應(yīng)用場(chǎng)景不同:DISTINCT 更適合單純的去重需求,GROUP BY 更適合分組統(tǒng)計(jì)需求。
- 性能略有不同:如果去重的字段有索引,那么 GROUP BY 和 DISTINCT 都可以使用索引,此情況它們的性能是相同的;而當(dāng)去重的字段沒有索引時(shí),DISTINCT 的性能就會(huì)高于 GROUP BY,因?yàn)樵?MySQL 8.0 之前,GROUP BY 有一個(gè)隱藏的功能會(huì)進(jìn)行默認(rèn)的排序,這樣就會(huì)觸發(fā) filesort 從而導(dǎo)致查詢性能降低。