新聞中心
在數(shù)據(jù)庫(kù)管理系統(tǒng)(DBMS)中,分組函數(shù)(Group Functions)是一類常用的函數(shù),它們可以對(duì)指定的數(shù)據(jù)進(jìn)行匯總、計(jì)數(shù)、平均數(shù)計(jì)算等操作。分組函數(shù)通常與分組操作(Group By)結(jié)合使用,用于對(duì)某些列進(jìn)行分組計(jì)算。然而,有時(shí)候我們會(huì)碰到一些情況,即使沒(méi)有進(jìn)行分組操作,分組函數(shù)的計(jì)算結(jié)果也與膽組相關(guān)。本文將詳細(xì)介紹在數(shù)據(jù)庫(kù)中分組函數(shù)的使用及其與膽組無(wú)關(guān)的情況。

成都創(chuàng)新互聯(lián)是一家專注于做網(wǎng)站、網(wǎng)站制作與策劃設(shè)計(jì),德令哈網(wǎng)站建設(shè)哪家好?成都創(chuàng)新互聯(lián)做網(wǎng)站,專注于網(wǎng)站建設(shè)十載,網(wǎng)設(shè)計(jì)領(lǐng)域的專業(yè)建站公司;建站業(yè)務(wù)涵蓋:德令哈等地區(qū)。德令哈做網(wǎng)站價(jià)格咨詢:13518219792
一、分組函數(shù)的基本用法
在講述分組函數(shù)與膽組無(wú)關(guān)之前,我們先來(lái)了解一下分組函數(shù)的基本用法。分組函數(shù)通常包括以下幾種:
1. AVG:用于計(jì)算指定列的平均值;
2. SUM:用于計(jì)算指定列的總和;
3. COUNT:用于統(tǒng)計(jì)指定列中非空值的數(shù)量;
4. MAX:用于求取指定列中的更大值;
5. MIN:用于求取指定列中的最小值。
例如,我們有一張學(xué)生成績(jī)表,其中包括學(xué)生姓名、所在班級(jí)、語(yǔ)文成績(jī)、數(shù)學(xué)成績(jī)、英語(yǔ)成績(jī)等字段。如果我們要求出每個(gè)班的平均成績(jī)、總成績(jī)、及格人數(shù)等指標(biāo),可以使用以下語(yǔ)句:
SELECT class, AVG(chinese_score), AVG(math_score), AVG(english_score), SUM(chinese_score + math_score + english_score) AS total_score, COUNT(CASE WHEN chinese_score >= 60 AND math_score >= 60 AND english_score >= 60 THEN 1 END) AS pass_cnt
FROM std_score
GROUP BY class;
其中,這個(gè)語(yǔ)句中的 AVG、SUM、COUNT 就是分組函數(shù),GROUP BY 關(guān)鍵字用于指定分組條件。
二、分組函數(shù)的計(jì)算并不總是和分組操作有關(guān)
通常情況下,分組函數(shù)的計(jì)算結(jié)果與分組條件有關(guān)。例如上述例子中,我們按照班級(jí)分組,求出了每個(gè)班級(jí)的平均成績(jī)、總成績(jī)及及格人數(shù)。但是,當(dāng)我們把 GROUP BY 關(guān)鍵字去掉時(shí),我們會(huì)發(fā)現(xiàn)計(jì)算結(jié)果依然正確:
SELECT AVG(chinese_score), AVG(math_score), AVG(english_score), SUM(chinese_score + math_score + english_score) AS total_score, COUNT(CASE WHEN chinese_score >= 60 AND math_score >= 60 AND english_score >= 60 THEN 1 END) AS pass_cnt
FROM std_score;
這是為什么呢?我們可以想象一下,以上語(yǔ)句的計(jì)算過(guò)程,實(shí)際上就是對(duì)整張表進(jìn)行了聚合。也就是說(shuō),這些分組函數(shù)并沒(méi)有通過(guò) GROUP BY 關(guān)鍵字來(lái)限定計(jì)算范圍,而是對(duì)表中所有行(或者符合條件的行)都進(jìn)行了計(jì)算。因此,它們的計(jì)算結(jié)果并不總是和分組操作相關(guān)。
不過(guò),需要注意的是,在某些情況下,去掉 GROUP BY 關(guān)鍵字會(huì)導(dǎo)致分組函數(shù)的計(jì)算結(jié)果變得毫無(wú)意義。例如,在以下語(yǔ)句中:
SELECT AVG(chinese_score), COUNT(chinese_score)
FROM std_score;
如果去掉 GROUP BY,計(jì)算結(jié)果就變成了所有成績(jī)的平均分和總數(shù)。顯然,這是毫無(wú)意義的。
三、分組函數(shù)在數(shù)據(jù)庫(kù)查詢中的應(yīng)用
分組函數(shù)在實(shí)際的數(shù)據(jù)庫(kù)查詢中應(yīng)用廣泛,可以用來(lái)快速計(jì)算統(tǒng)計(jì)數(shù)據(jù),也可以用來(lái)制作報(bào)表等。例如,以下是一個(gè)根據(jù)訂單狀態(tài)統(tǒng)計(jì)銷售額的例子:
SELECT status, SUM(price * quantity) AS sales
FROM orders
GROUP BY status;
在這個(gè)例子中,我們使用 SUM 函數(shù)計(jì)算了訂單中所有商品的銷售額,并按照訂單狀態(tài)分組進(jìn)行統(tǒng)計(jì)。
分組函數(shù)還可以用于查詢某些列的最值等數(shù)據(jù)。例如,以下是一個(gè)查詢產(chǎn)品庫(kù)存最多的前十個(gè)產(chǎn)品的例子:
SELECT product_id, SUM(quantity) AS total_quantity
FROM product_storage
GROUP BY product_id
ORDER BY total_quantity DESC
LIMIT 10;
在這個(gè)例子中,我們使用 SUM 函數(shù)計(jì)算了每個(gè)產(chǎn)品的庫(kù)存總量,并按照產(chǎn)品編號(hào)進(jìn)行分組統(tǒng)計(jì)。然后,使用 ORDER BY 關(guān)鍵字對(duì)結(jié)果進(jìn)行排序,使用 LIMIT 關(guān)鍵字取出前十個(gè)結(jié)果即可。
四、
數(shù)據(jù)庫(kù)中的分組函數(shù)是常用的一類函數(shù),可以用于聚合計(jì)算、統(tǒng)計(jì)數(shù)據(jù)、制作報(bào)表等多種場(chǎng)景。雖然分組函數(shù)通常和 GROUP BY 關(guān)鍵字結(jié)合使用,但是在某些情況下,分組函數(shù)的計(jì)算結(jié)果并不與分組操作相關(guān)。因此,在使用分組函數(shù)時(shí)需要根據(jù)實(shí)際情況進(jìn)行判斷。
相關(guān)問(wèn)題拓展閱讀:
- order by 和 group by 的區(qū)別
- mysql數(shù)據(jù)庫(kù) group by 報(bào)錯(cuò) 原理是什么?
order by 和 group by 的區(qū)別
select a.name, max(a.sex) from a group by a.name order by a.sex asc
group by 用來(lái)分組如春,order by 用來(lái)渣睜耐早姿排序
order by
和 group by的區(qū)別為:指代不同、側(cè)重點(diǎn)不同、引證用法不同
一、指代不同
1、order by:排序依據(jù)。
2、group by:進(jìn)行分組。
二、側(cè)重點(diǎn)不同
1、order by:用來(lái)對(duì)數(shù)據(jù)庫(kù)的一組數(shù)據(jù)進(jìn)行排序。
2、group by:指定的規(guī)則對(duì)數(shù)據(jù)進(jìn)行分組,所謂的分組就是將一個(gè)“
數(shù)據(jù)集
”劃分成若干個(gè)“小區(qū)域”,然后針對(duì)若干個(gè)“小區(qū)域”進(jìn)行數(shù)據(jù)處理。
三、引證用法不同
1、order by:order作“次序,順序”“治安,秩序”“整齊,有條理”解時(shí),是
不可數(shù)名詞
。作“訂購(gòu),訂貨”“命令,囑咐”“匯票,匯單”解時(shí),是可數(shù)名詞。
2、group by:group的基本意思是“群,團(tuán)體,組類”,指由很多的人或物偶然鍵譽(yù)或有意組成的一個(gè)有秩序、有組織的整體,稿告段有時(shí)也可指較小的“人群”,還可以指一個(gè)大型的商業(yè)機(jī)構(gòu),即“集團(tuán)”或某種“類別”友配。
order by 和 group by 的派返區(qū)別:
1,order by 從英文里理解就是行的排序方式,默認(rèn)的為升序。 order by 后面必須列出排序的字段名,可以是多個(gè)字段名。
2,group by 從英文里理解就是分組。必須有“聚合函數(shù)”來(lái)配合才能使用,使用時(shí)至少需要一個(gè)分組標(biāo)志字段。
注意:聚合函數(shù)是—sum()、count()、avg()等都是“聚合函數(shù)”
3,在sql命令格式使用的先后順序上,group by 先于 order by。
在Sql中也可亂頌以說(shuō)order by是按字段排序,group by 是按字段分類
通常order by 和group by 沒(méi)有太多的關(guān)系,但是它們常常組合在一起用,完成分組加排序的功能。
如有下表:
執(zhí)行這個(gè)語(yǔ)句是可以的:
如果執(zhí)行下面語(yǔ)句就不行:
正確的應(yīng)該是:
group by 塵陪饑的目的就是要將數(shù)據(jù)分類匯總。
如:
select 類別, sum(數(shù)量) as 數(shù)量之和 from A group by 類別
這就是簡(jiǎn)單Group By,返回結(jié)果會(huì)是分類匯總的結(jié)果。
order by 以…排序
group by 以…分組
order by 排序查詢、asc升序、desc降序
示例:
select * from 學(xué)生表 order by 年齡 查詢學(xué)生表信息、按年齡的升序(默認(rèn)、可缺省、從低到高早指)排列顯示
也可以多條件排序、 比如 order by 年陸彎配齡,成績(jī) desc 按年齡升序排列后、再按成績(jī)降序排列
group by 分組查詢、having 只能用于group by子句、作用于組內(nèi),having條件子句可以直接跟函數(shù)表達(dá)式。使用group by 子句的查鬧衫詢語(yǔ)句需要使用聚合函數(shù)。
示例:
select 學(xué)號(hào),SUM(成績(jī)) from 選課表 group by 學(xué)號(hào) 按學(xué)號(hào)分組、查詢每個(gè)學(xué)號(hào)的總成績(jī)
select 學(xué)號(hào),AVG(成績(jī)) from 選課表
group by 學(xué)號(hào)
having AVG(成績(jī))>(select AVG(成績(jī)) from 選課表 where 課程號(hào)=’001′)
order by AVG(成績(jī)) desc
查詢平均成績(jī)大于001課程平均成績(jī)的學(xué)號(hào)、并按平均成績(jī)的降序排列
mysql數(shù)據(jù)庫(kù) group by 報(bào)錯(cuò) 原理是什么?
在日常查詢中,索引或其他數(shù)據(jù)查找的方法可能不是查詢執(zhí)行中更高昂的部分,例如:MySQL GROUP BY 可能負(fù)責(zé)查詢執(zhí)行時(shí)間 90% 還多。MySQL 執(zhí)行 GROUP BY 時(shí)的主要復(fù)雜性是計(jì)算 GROUP BY 語(yǔ)句磨沒(méi)中的聚合函數(shù)。UDF 聚合函數(shù)是一個(gè)接一個(gè)地獲得構(gòu)成單個(gè)組的所有值。這樣,它可以在移動(dòng)到另一個(gè)組之前計(jì)算單個(gè)組的聚合函數(shù)值。當(dāng)然,問(wèn)題在于,在大多數(shù)情況下,源數(shù)據(jù)值不會(huì)被分組。來(lái)自各種組的值在處理期間彼此跟隨。因此,我們需要一個(gè)特殊的步驟。
處理 MySQL GROUP BY讓瞎碧納我們看看之前看過(guò)的同一張table: mysql> show create table tbl G *************************** 1. row ***************************Table: tbl Create Table: CREATE TABLE `tbl` ( `id` int(11) NOT NULL AUTO_INCREMENT, `k` int(11) NOT NULL DEFAULT ‘0’, `g` int(10) unsigned NOT NULL, PRIMARY KEY (`id`), KEY `k` (`k`) ) ENGINE=InnoDB AUTO_INCREMENT=DEFAULT CHARSET=latinrow in set (0.00 sec)
并且以不同方式執(zhí)行相同的 GROUP BY 語(yǔ)句:
1、MySQL中 的 Index Ordered GROUP BY
mysql> select k, count(*) c from tbl group by k order by k limit 5;
+—+—+
| k | c |
+—+—+
| 2 | 3 |
| 4 | 1 |
| 5 | 2 |
| 8 | 1 |
| 9 | 1 |
+—+—+
5 rows in set (0.00 sec)
mysql> explain select k, count(*) c from tbl group by k order by k limit 5 G
*************************** 1. row ***************************
id: 1
select_type: SIMPLE
table: tbl
partitions: NULL
type: index
possible_keys: k
key: k
key_len: 4
ref: NULL
rows: 5
filtered: 100.00
Extra: Using index
1 row in set, 1 warning (0.00 sec)
在這種情況下,我們?cè)?GROUP BY 的列上有一個(gè)索引。這樣,我們可以逐組掃描數(shù)據(jù)并動(dòng)態(tài)執(zhí)行 GROUP BY(低慧弊成本)。當(dāng)我們使用 LIMIT 限制我們檢索的組的數(shù)量或使用“覆蓋索引”時(shí),特別有效,因?yàn)轫樞蛩饕龗呙枋且环N非常快速的操作。
如果您有少量組,并且沒(méi)有覆蓋索引,索引順序掃描可能會(huì)導(dǎo)致大量 IO。所以這可能不是更優(yōu)化的計(jì)劃。
2、MySQL 中的外部排序 GROUP BY
mysql> explain select SQL_BIG_RESULT g, count(*) c from tbl group by g limit 5 G
*************************** 1. row ***************************
id: 1
select_type: SIMPLE
table: tbl
partitions: NULL
type: ALL
possible_keys: NULL
key: NULL
key_len: NULL
ref: NULL
rows:
filtered: 100.00
Extra: Using filesort
1 row in set, 1 warning (0.00 sec)
mysql> select SQL_BIG_RESULT g, count(*) c from tbl group by g limit 5;
+—+—+
| g | c |
+—+—+
| 0 | 1 |
| 1 | 2 |
| 4 | 1 |
| 5 | 1 |
| 6 | 2 |
+—+—+
5 rows in set (0.88 sec)
如果我們沒(méi)有允許我們按組順序掃描數(shù)據(jù)的索引,我們可以通過(guò)外部排序(在 MySQL 中也稱為“filesort”)來(lái)獲取數(shù)據(jù)。你可能會(huì)注意到我在這里使用 SQL_BIG_RESULT 提示來(lái)獲得這個(gè)計(jì)劃。沒(méi)有它,MySQL 在這種情況下不會(huì)選擇這個(gè)計(jì)劃。
一般來(lái)說(shuō),MySQL 只有在我們擁有大量組時(shí)才更喜歡使用這個(gè)計(jì)劃,因?yàn)樵谶@種情況下,排序比擁有臨時(shí)表更有效(我們將在下面討論)。
3、MySQL中 的臨時(shí)表 GROUP BY
mysql> explain select g, sum(g) s from tbl group by g limit 5 G
*************************** 1. row ***************************
id: 1
select_type: SIMPLE
table: tbl
partitions: NULL
type: ALL
possible_keys: NULL
key: NULL
key_len: NULL
ref: NULL
rows:
filtered: 100.00
Extra: Using temporary
1 row in set, 1 warning (0.00 sec)
mysql> select g, sum(g) s from tbl group by g order by null limit 5;
+—+——+
| g | s |
+—+——+
| 0 | 0 |
| 1 | 2 |
| 4 | 4 |
| 5 | 5 |
| 6 | 12 |
+—+——+
5 rows in set (7.75 sec)
在這種情況下,MySQL 也會(huì)進(jìn)行全表掃描。但它不是運(yùn)行額外的排序傳遞,而是創(chuàng)建一個(gè)臨時(shí)表。此臨時(shí)表每組包含一行,并且對(duì)于每個(gè)傳入行,將更新相應(yīng)組的值。很多更新!雖然這在內(nèi)存中可能是合理的,但如果結(jié)果表太大以至于更新將導(dǎo)致大量磁盤(pán) IO,則會(huì)變得非常昂貴。在這種情況下,外部分揀計(jì)劃通常更好。請(qǐng)注意,雖然 MySQL 默認(rèn)選擇此計(jì)劃用于此用例,但如果我們不提供任何提示,它幾乎比我們使用 SQL_BIG_RESULT 提示的計(jì)劃慢 10 倍 。您可能會(huì)注意到我在此查詢中添加了“ ORDER BY NULL ”。這是為了向您展示“清理”臨時(shí)表的唯一計(jì)劃。沒(méi)有它,我們得到這個(gè)計(jì)劃: mysql> explain select g, sum(g) s from tbl group by g limit 5 G *************************** 1. row ***************************id:select_type: SIMPLEtable: tbl partitions: NULLtype: ALL possible_keys: NULLkey: NULLkey_len: NULLref: NULLrows: filtered: 100.Extra: Using temporary; Using filesort 1 row in set, 1 warning (0.00 sec)
在其中,我們獲得了 temporary 和 filesort “兩最糟糕的”提示。MySQL 5.7 總是返回按組順序排序的 GROUP BY 結(jié)果,即使查詢不需要它(這可能需要昂貴的額外排序傳遞)。ORDER BY NULL 表示應(yīng)用程序不需要這個(gè)。您應(yīng)該注意,在某些情況下 – 例如使用聚合函數(shù)訪問(wèn)不同表中的列的 JOIN 查詢 – 使用 GROUP BY 的臨時(shí)表可能是唯一的選擇。
如果要強(qiáng)制 MySQL 使用為 GROUP BY 執(zhí)行臨時(shí)表的計(jì)劃,可以使用 SQL_ALL_RESULT 提示。
4、MySQL 中的索引基于跳過(guò)掃描的 GROUP BY前三個(gè) GROUP BY 執(zhí)行方法適用于所有聚合函數(shù)。然而,其中一些人有第四種方法。
mysql> explain select k,max(id) from tbl group by k G
*************************** 1. row ***************************
id: 1
select_type: SIMPLE
table: tbl
partitions: NULL
type: range
possible_keys: k
key: k
key_len: 4
ref: NULL
rows: 2
filtered: 100.00
Extra: Using index for group-by
1 row in set, 1 warning (0.00 sec)
mysql> select k,max(id) from tbl group by k;
+—++
| k | max(id) |
+—++
| 0 ||
| 1 ||
| 2 ||
| 3 ||
| 4 ||
+—++
5 rows in set (0.00 sec)
此方法僅適用于非常特殊的聚合函數(shù):MIN() 和 MAX()。這些并不需要遍歷組中的所有行來(lái)計(jì)算值。他們可以直接跳轉(zhuǎn)到組中的最小或更大組值(如果有這樣的索引)。如果索引僅建立在 (K) 列上,如何找到每個(gè)組的 MAX(ID) 值?這是一個(gè) InnoDB 表。記住 InnoDB 表有效地將 PRIMARY KEY 附加到所有索引。(K) 變?yōu)?(K,ID),允許我們對(duì)此查詢使用 Skip-Scan 優(yōu)化。僅當(dāng)每個(gè)組有大量行時(shí)才會(huì)啟用此優(yōu)化。否則,MySQL 更傾向于使用更傳統(tǒng)的方法來(lái)執(zhí)行此查詢(如方法#1中詳述的索引有序 GROUP BY)。雖然我們使用 MIN() / MAX() 聚合函數(shù),但其他優(yōu)化也適用于它們。例如,如果您有一個(gè)沒(méi)有 GROUP BY 的聚合函數(shù)(實(shí)際上所有表都有一個(gè)組),MySQL 在統(tǒng)計(jì)分析階段從索引中獲取這些值,并避免在執(zhí)行階段完全讀取表: mysql> explain select max(k) from tbl G *************************** 1. row ***************************id:select_type: SIMPLEtable: NULL partitions: NULLtype: NULL possible_keys: NULLkey: NULLkey_len: NULLref: NULLrows: NULLfiltered: NULLExtra: Select tables optimized away 1 row in set, 1 warning (0.00 sec)
過(guò)濾和分組
我們已經(jīng)研究了 MySQL 執(zhí)行 GROUP BY 的四種方式。為簡(jiǎn)單起見(jiàn),我在整個(gè)表上使用了 GROUP BY,沒(méi)有應(yīng)用過(guò)濾。當(dāng)您有 WHERE 子句時(shí),相同的概念適用: mysql> explain select g, sum(g) s from tbl where k>4 group by g order by NULL limit 5 G *************************** 1. row ***************************id:select_type: SIMPLEtable: tbl partitions: NULLtype: range possible_keys: kkey: kkey_len: ref: NULLrows:filtered: 100.Extra: Using index condition; Using temporary 1 row in set, 1 warning (0.00 sec)
對(duì)于這種情況,我們使用K列上的范圍進(jìn)行數(shù)據(jù)過(guò)濾/查找,并在有臨時(shí)表時(shí)執(zhí)行 GROUP BY。在某些情況下,方法不會(huì)發(fā)生沖突。但是,在其他情況下,我們必須選擇使用 GROUP BY 的一個(gè)索引或其他索引進(jìn)行過(guò)濾:
mysql> alter table tbl add key(g);
Query OK, 0 rows affected (4.17 sec)
Records: 0 Duplicates: 0 Warnings: 0
mysql> explain select g, sum(g) s from tbl where k>1 group by g limit 5 G
*************************** 1. row ***************************
id: 1
select_type: SIMPLE
table: tbl
partitions: NULL
type: index
possible_keys: k,g
key: g
key_len: 4
ref: NULL
rows: 16
filtered: 50.00
Extra: Using where
1 row in set, 1 warning (0.00 sec)
mysql> explain select g, sum(g) s from tbl where k>4 group by g limit 5 G
*************************** 1. row ***************************
id: 1
select_type: SIMPLE
table: tbl
partitions: NULL
type: range
possible_keys: k,g
key: k
key_len: 4
ref: NULL
rows: 1
filtered: 100.00
Extra: Using index condition; Using temporary; Using filesort
1 row in set, 1 warning (0.00 sec)
根據(jù)此查詢中使用的特定常量,我們可以看到我們對(duì) GROUP BY 使用索引順序掃描(并從索引中“放棄”以解析 WHERE 子句),或者使用索引來(lái)解析 WHERE 子句(但使用臨時(shí)表來(lái)解析 GROUP BY)。根據(jù)我的經(jīng)驗(yàn),這就是 MySQL GROUP BY 并不總是做出正確選擇的地方。您可能需要使用 FORCE INDEX 以您希望的方式執(zhí)行查詢。
group by 與 count 一起的話不能直接寫(xiě),
得用子查詢
數(shù)據(jù)庫(kù)不是膽組分組函數(shù)的介紹就聊到這里吧,感謝你花時(shí)間閱讀本站內(nèi)容,更多關(guān)于數(shù)據(jù)庫(kù)不是膽組分組函數(shù),數(shù)據(jù)庫(kù)中的分組函數(shù)與膽組無(wú)關(guān),order by 和 group by 的區(qū)別,mysql數(shù)據(jù)庫(kù) group by 報(bào)錯(cuò) 原理是什么?的信息別忘了在本站進(jìn)行查找喔。
成都網(wǎng)站營(yíng)銷推廣找創(chuàng)新互聯(lián),全國(guó)分站站群網(wǎng)站搭建更好做SEO營(yíng)銷。
創(chuàng)新互聯(lián)(www.cdcxhl.com)四川成都IDC基礎(chǔ)服務(wù)商,價(jià)格厚道。提供成都服務(wù)器托管租用、綿陽(yáng)服務(wù)器租用托管、重慶服務(wù)器托管租用、貴陽(yáng)服務(wù)器機(jī)房服務(wù)器托管租用。
本文名稱:數(shù)據(jù)庫(kù)中的分組函數(shù)與膽組無(wú)關(guān) (數(shù)據(jù)庫(kù)不是膽組分組函數(shù))
當(dāng)前URL:http://m.5511xx.com/article/cdhoddg.html


咨詢
建站咨詢
