亚洲精品久久久中文字幕-亚洲精品久久片久久-亚洲精品久久青草-亚洲精品久久婷婷爱久久婷婷-亚洲精品久久午夜香蕉

您的位置:首頁技術文章
文章詳情頁

MySQL基礎教程13 —— 函數之與GROUP BY子句同時使用的函數

瀏覽:7日期:2023-10-17 17:52:24
1.GROUP BY(聚合)函數

本章論述了用于一組數值操作的group (集合)函數。除非另作說明,group函數會忽略NULL值。

假如你在一個不包含ROUP BY子句的語句中使用一個group函數 ,它相當于對所有行進行分組。

AVG([DISTINCT]expr)

返回expr的平均值。DISTINCT選項可用于返回expr的不同值的平均值。

若找不到匹配的行,則AVG()返回NULL。

mysql>SELECT student_name, AVG(test_score)->FROM student-> GROUP BY student_name;

BIT_AND(expr)

返回expr中所有比特的bitwise AND。計算執行的精確度為64比特(BIGINT)。

若找不到匹配的行,則這個函數返回18446744073709551615。(這是無符號BIGINT值,所有比特被設置為1)。

BIT_OR(expr)

返回expr中所有比特的bitwise OR。計算執行的精確度為64比特(BIGINT)。

若找不到匹配的行,則函數返回0。

BIT_XOR(expr)

返回expr中所有比特的bitwise XOR。計算執行的精確度為64比特(BIGINT)。

若找不到匹配的行,則函數返回0。

COUNT(expr)

返回SELECT語句檢索到的行中非NULL值的數目。

若找不到匹配的行,則COUNT()返回0。

mysql>SELECT student.student_name,COUNT(*)->FROM student,course->WHERE student.student_id=course.student_id->GROUP BY student_name;

COUNT(*)的稍微不同之處在于,它返回檢索行的數目, 不論其是否包含NULL值。

SELECT從一個表中檢索,而不檢索其它的列,并且沒有WHERE子句時,COUNT(*)被優化到最快的返回速度。例如:

mysql>SELECT COUNT(*) FROM student;

這個優化僅適用于MyISAM表,原因是這些表類型會儲存一個函數返回記錄的精確數量,而且非常容易訪問。對于事務型的存儲引擎(InnoDB, BDB),存儲一個精確行數的問題比較多,原因是可能會發生多重事物處理,而每個都可能會對行數產生影響。

COUNT(DISTINCTexpr,[expr...])

返回不同的非NULL值數目。

若找不到匹配的項,則COUNT(DISTINCT)返回0。

mysql>SELECT COUNT(DISTINCT results) FROM student;

在MySQL中,你通過給定一個表達式列表而獲取不包含NULL不同表達式組合的數目。在標準SQL中,你將必須在COUNT(DISTINCT ...)中連接所有表達式。

GROUP_CONCAT(expr)

該函數返回帶有來自一個組的連接的非NULL值的字符串結果。其完整的語法如下所示:

GROUP_CONCAT([DISTINCT]expr[,expr...]

[ORDER BY {unsigned_integer|col_name|expr}

[ASC | DESC] [,col_name...]]

[SEPARATORstr_val])

mysql>SELECT student_name,->GROUP_CONCAT(test_score)->FROM student->GROUP BY student_name;

Or:

mysql>SELECT student_name,->GROUP_CONCAT(DISTINCT test_score->ORDER BY test_score DESC SEPARATOR ’ ’)->FROM student->GROUP BY student_name;

在MySQL中,你可以獲取表達式組合的連接值。你可以使用DISTINCT刪去重復值。假若你希望多結果值進行排序,則應該使用 ORDER BY子句。若要按相反順序排列,將DESC (遞減)關鍵詞添加到你要用ORDER BY子句進行排序的列名稱中。默認順序為升序;可使用ASC將其明確指定。 SEPARATOR后面跟隨應該被插入結果的值中間的字符串值。默認為逗號(‘,’)。通過指定SEPARATOR ’’,你可以刪除所有分隔符。

使用group_concat_max_len系統變量,你可以設置允許的最大長度。程序中進行這項操作的語法如下,其中val是一個無符號整數:

SET [SESSION | GLOBAL] group_concat_max_len = val;

若已經設置了最大長度, 則結果被截至這個最大長度。

MIN([DISTINCT]expr), MAX([DISTINCT]expr)

返回expr的最小值和最大值。MIN()和MAX()的取值可以是一個字符串參數;在這些情況下, 它們返回最小或最大字符串值。DISTINCT關鍵詞可以被用來查找expr的不同值的最小或最大值,然而,這產生的結果與省略DISTINCT的結果相同。

若找不到匹配的行,MIN()和MAX()返回NULL。

mysql>SELECT student_name, MIN(test_score), MAX(test_score)-> FROM student-> GROUP BY student_name;

對于MIN()、MAX()和其它集合函數,MySQL當前按照它們的字符串值而非字符串在集合中的相關位置比較ENUM和SET列。這同ORDER BY比較二者的方式有所不同。這一點應該在MySQL的未來版本中得到改善。

STD(expr) STDDEV(expr)

返回expr的總體標準偏差。這是標準SQL的延伸。這個函數的STDDEV()形式用來提供和Oracle的兼容性。可使用標準SQL函數STDDEV_POP()進行代替。

若找不到匹配的行,則這些函數返回NULL。

STDDEV_POP(expr)

返回expr的總體標準偏差(VAR_POP()的平方根)。你也可以使用 STD()或STDDEV(),它們具有相同的意義,然而不是標準的SQL。

若找不到匹配的行,則STDDEV_POP()返回NULL。

STDDEV_SAMP(expr)

返回expr的樣本標準差( VAR_SAMP()的平方根)。

若找不到匹配的行,則STDDEV_SAMP()返回NULL。

SUM([DISTINCT]expr)

返回expr的總數。 若返回集合中無任何行,則SUM()返回NULL。DISTINCT關鍵詞可用于MySQL 5.1中,求得expr不同值的總和。

若找不到匹配的行,則SUM()返回NULL。

VAR_POP(expr)

返回expr總體標準方差。它將行視為總體,而不是一個樣本, 所以它將行數作為分母。你也可以使用VARIANCE(),它具有相同的意義然而不是 標準的SQL。

若找不到匹配的項,則VAR_POP()返回NULL。

VAR_SAMP(expr)

返回expr的樣本方差。更確切的說,分母的數字是行數減去1。

若找不到匹配的行,則VAR_SAMP()返回NULL。

VARIANCE(expr)

返回expr的總體標準方差。這是標準SQL的延伸。可使用標準SQL函數VAR_POP()進行代替。

若找不到匹配的項,則VARIANCE()返回NULL。

2.GROUP BY修改程序

GROUP BY子句允許一個將額外行添加到簡略輸出端WITH ROLLUP修飾符。這些行代表高層(或高聚集)簡略操作。ROLLUP因而允許你在多層分析的角度回答有關問詢的問題。例如,它可以用來向OLAP (聯機分析處理)操作提供支持。

設想一個名為sales的表具有年份、國家、產品及記錄銷售利潤的利潤列:

CREATE TABLE sales( year INT NOT NULL, country VARCHAR(20) NOT NULL, product VARCHAR(32) NOT NULL, profit INT);

可以使用這樣的簡單GROUP BY,每年對表的內容做一次總結:

mysql>SELECT year, SUM(profit) FROM sales GROUP BY year;+------+-------------+| year | SUM(profit) |+------+-------------+| 2000 | 4525 || 2001 | 3010 |+------+-------------+

這個輸出結果顯示了每年的總利潤, 但如果你也想確定所有年份的總利潤,你必須自己累加每年的單個值或運行一個加法詢問。

或者你可以使用ROLLUP,它能用一個問詢提供雙層分析。將一個WITH ROLLUP修飾符添加到GROUP BY語句,使詢問產生另一行結果,該行顯示了所有年份的總價值:

mysql>SELECT year, SUM(profit) FROM sales GROUP BY year WITH ROLLUP;+------+-------------+| year | SUM(profit) |+------+-------------+| 2000 | 4525 || 2001 | 3010 || NULL | 7535 |+------+-------------+

總計高聚集行被年份列中的NULL值標出。

當有多重GROUP BY列時,ROLLUP產生的效果更加復雜。這時,每次在除了最后一個分類列之外的任何列出現一個 “break”(值的改變),則問訊會產生一個高聚集累計行。

例如,在沒有ROLLUP的情況下,一個以年、國家和產品為基礎的關于sales表的一覽表可能如下所示:

mysql>SELECT year, country, product, SUM(profit)->FROM sales->GROUP BY year, country, product;+------+---------+------------+-------------+| year | country | product | SUM(profit) |+------+---------+------------+-------------+| 2000 | Finland | Computer | 1500 || 2000 | Finland | Phone | 100 || 2000 | India | Calculator | 150 || 2000 | India | Computer | 1200 || 2000 | USA | Calculator | 75 || 2000 | USA | Computer | 1500 || 2001 | Finland | Phone | 10 || 2001 | USA | Calculator | 50 || 2001 | USA | Computer | 2700 || 2001 | USA | TV | 250 |+------+---------+------------+-------------+

表示總值的輸出結果僅位于年/國家/產品的分析級別。當添加了ROLLUP后, 問詢會產生一些額外的行:

mysql>SELECT year, country, product, SUM(profit) ->FROM sales ->GROUP BY year, country, product WITH ROLLUP;+------+---------+------------+-------------+| year | country | product | SUM(profit) |+------+---------+------------+-------------+| 2000 | Finland | Computer | 1500 || 2000 | Finland | Phone | 100 || 2000 | Finland | NULL | 1600 || 2000 | India | Calculator | 150 || 2000 | India | Computer | 1200 || 2000 | India | NULL | 1350 || 2000 | USA | Calculator | 75 || 2000 | USA | Computer | 1500 || 2000 | USA | NULL | 1575 || 2000 | NULL | NULL | 4525 || 2001 | Finland | Phone | 10 || 2001 | Finland | NULL | 10 || 2001 | USA | Calculator | 50 || 2001 | USA | Computer | 2700 || 2001 | USA | TV | 250 || 2001 | USA | NULL | 3000 || 2001 | NULL | NULL | 3010 || NULL | NULL | NULL | 7535 |+------+---------+------------+-------------+

對于這個問詢, 添加ROLLUP子句使村輸出結果包含了四層分析的簡略信息,而不只是一個下面是怎樣解釋 ROLLUP輸出:

一組給定的年份和國家的每組產品行后面,會產生一個額外的總計行, 顯示所有產品的總值。這些行將產品列設置為NULL。一組給定年份的行后面,會產生一個額外的總計行,顯示所有國家和產品的總值。這些行將國家和產品列設置為 NULL。最后,在所有其它行后面,會產生一個額外的總計列,顯示所有年份、國家及產品的總值。 這一行將年份、國家和產品列設置為NULL。

使用ROLLUP時的其它注意事項

以下各項列出了一些MySQL執行ROLLUP的特殊狀態:

當你使用ROLLUP時,你不能同時使用ORDER BY子句進行結果排序。換言之,ROLLUP和ORDER BY是互相排斥的。然而,你仍可以對排序進行一些控制。在MySQL中,GROUP BY可以對結果進行排序,而且你可以在GROUP BY列表指定的列中使用明確的ASC和DESC關鍵詞,從而對個別列進行排序。(不論如何排序被ROLLUP添加的較高級別的總計行仍出現在它們被計算出的行后面)。

LIMIT可用來限制返回客戶端的行數。LIMIT用在ROLLUP后面,因此這個限制 會取消被ROLLUP添加的行。例如:

mysql>SELECT year, country, product, SUM(profit) ->FROM sales ->GROUP BY year, country, product WITH ROLLUP ->LIMIT 5;+------+---------+------------+-------------+| year | country | product | SUM(profit) |+------+---------+------------+-------------+| 2000 | Finland | Computer | 1500 || 2000 | Finland | Phone | 100 || 2000 | Finland | NULL | 1600 || 2000 | India | Calculator | 150 || 2000 | India | Computer | 1200 |+------+---------+------------+-------------+

將ROLLUP同LIMIT一起使用可能會產生更加難以解釋的結果,原因是對于理解高聚集行,你所掌握的上下文較少。

在每個高聚集行中的NULL指示符會在該行被送至客戶端時產生。服務器會查看最左邊的改變值后面的GROUP BY子句指定的列。對于任何結果集合中的,有一個詞匹配這些名字的列,其值被設為NULL。(若你使用列數字指定了分組列,則服務器會通過數字確定將哪個列設置為NULL)。

由于在高聚集行中的NULL值在問詢處理階段被放入結果集合中,你無法將它們在問詢本身中作為NULL值檢驗。例如,你無法將HAVING product IS NULL添加到問詢中,從而在輸出結果中刪去除了高聚集行以外的部分。

另一方面, NULL值在客戶端不以NULL的形式出現, 因而可以使用任何MySQL客戶端編程接口進行檢驗。

3.具有隱含字段的GROUP BY

MySQL擴展了GROUP BY的用途,因此你可以使用SELECT列表中不出現在GROUP BY語句中的列或運算。這代表 “對該組的任何可能值 ”。你可以通過避免排序和對不必要項分組的辦法得到它更好的性能。例如,在下列問詢中,你無須對customer.name進行分組:

mysql>SELECT order.custid, customer.name, MAX(payments) ->FROM order,customer ->WHERE order.custid = customer.custid -> GROUP BY order.custid;

在標準SQL中,你必須將customer.name添加到GROUP BY子句中。在MySQL中,假如你不在ANSI模式中運行,則這個名字就是多余的。

假如你從GROUP BY部分省略的列在該組中不是唯一的,那么不要使用這個功能!你會得到非預測性結果。

在有些情況下,你可以使用MIN()和MAX()獲取一個特殊的列值,即使他不是唯一的。下面給出了來自包含排序列中最小值的列中的值:

SUBSTR(MIN(CONCAT(RPAD(sort,6,’ ’),column)),7)

注意,假如你正在嘗試遵循標準SQL,你不能使用GROUP BY或ORDER BY子句中的表達式。你可以通過使用表達式的別名繞過這一限制:

mysql>SELECT id,FLOOR(value/100) AS val ->FROMtbl_name ->GROUP BY id, val ORDER BY val;

然而, MySQL允許你使用GROUP BY及ORDER BY子句中的表達式。例如:

mysql>SELECT id, FLOOR(value/100) FROMtbl_nameORDER BY RAND();

標簽: MySQL 數據庫
相關文章:
主站蜘蛛池模板: 吊操视频| 尤物视频免费在线观看 | 日本一级毛片在线播放 | 欧美午夜免费毛片a级 | 国产成人精品1024在线 | 欧美中文字幕 | 日本一级毛片免费完整视频2020 | 免费视频日本xvideos | 欧美一级毛片美99毛片 | japanese色系国产在线高清 | 亚洲黄色网址大全 | 青草视频久久 | 国产欧美综合精品一区二区 | 亚洲色图1 | 风间中文字幕亚洲一区中文馆 | 精品中文字幕制服中文 | 毛片一区| 国产精品国产三级国产专播下 | 国产免费一区二区三区 | 国产精品久久久久久久久鸭 | 欧美日韩一区二区三区四区 | 婷婷色网| 亚洲午夜久久久久久91 | 国产黄三级三·级三级 | 国产足控福利视频入口 | 在线精品自拍亚洲第一区 | 嫩草网站永久入口 | 亚洲国产精品v在线播放 | 2015xxx小明永久免费 | 国产大片91精品免费观看男同 | 亚洲午夜久久久精品影院视色 | 国产亚洲新品一区二区 | 国产精品免费拍拍1000部 | 一级做a爰片久久毛片 | 免费大片黄在线观看 | 亚洲国产第一区 | 色在线看| 最新国产中文字幕 | 成年人毛片 | 国产视频黄色 | 亚洲精品一区二区三区香蕉在线看 |