Group by函數

Group by函數

1.前言

在數據庫操作中分組操作經常用到。本文就來聊一聊,數據庫中分組函數GROUP BY ;

2.創建測試表

示例表

CREATE TABLE `group_by_test` (
	`id` INT ( 10 ) NOT NULL AUTO_INCREMENT COMMENT '自增ID',
	`field_one` VARCHAR ( 64 ) NOT NULL DEFAULT '' COMMENT '字段1',
	`field_two` VARCHAR ( 64 ) NOT NULL DEFAULT '' COMMENT '字段2',
	`field_three` VARCHAR ( 64 ) NOT NULL DEFAULT '' COMMENT '字段3',
PRIMARY KEY ( `id` ) USING BTREE 
) ENGINE = INNODB DEFAULT CHARSET = utf8 COMMENT = 'group by 函數測試表';

3.SELECT後允許跟非分組字段嗎?

問題:這個SQL可以執行嗎?

SELECT
	field_one,
	field_two,
	field_three 
FROM
	group_by_test 
GROUP BY field_one

答案:執行以上SQL是需要有條件的 ;

mysql數據庫的中有一個環境變量sql_mode,定義了mysql應該支持的sql語法,數據校驗等!
如果ONLY_FULL_GROUP_BY啓用了 SQL模式(默認情況下爲SQL模式),則MySQL拒絕查詢
image.png
MySQL官網中是這樣介紹的:
image.png

簡譯:

  • 不允許選擇列表,HAVING條件或ORDER BY列表引用未在GROUP BY子句中命名的未聚合列的查詢;

綜上所述:
如果在SELECT中的列,沒有在GROUP BY中出現,若ONLY_FULL_GROUP_BY啓用了 SQL模式那麼將認爲這個SQL是不合法的,

查看

查看當前連接會話的sql模式:
mysql> select @@session.sql_mode;
或者從環境變量裏取
mysql> show variables like "sql_mode";
查看全局sql_mode設置:
mysql> select @@global.sql_mode;
只設置global,需要重新連接進來纔會生效

**

sql_mode值與含義

ONLY_FULL_GROUP_BY 對於GROUP BY聚合操作,如果在SELECT中的列,沒有在GROUP BY中出現,那麼將認爲這個SQL是不合法的,因爲列不在GROUP BY從句中
STRICT_TRANS_TABLES 在該模式下,如果一個值不能插入到一個事務表中,則中斷當前的操作,對非事務表不做任何限制
NO_ZERO_IN_DATE 在嚴格模式,不接受月或日部分爲0的日期。如果使用IGNORE選項,我們爲類似的日期插入’0000-00-00’。在非嚴格模式,可以接受該日期,但會生成警告。
NO_ZERO_DATE 在嚴格模式,不要將 '0000-00-00’做爲合法日期。你仍然可以用IGNORE選項插入零日期。在非嚴格模式,可以接受該日期,但會生成警告
ERROR_FOR_DIVISION_BY_ZERO 在嚴格模式,在INSERT或UPDATE過程中,如果被零除(或MOD(X,0)),則產生錯誤(否則爲警告)。如果未給出該模式,被零除時MySQL返回NULL。如果用到INSERT IGNORE或UPDATE IGNORE中,MySQL生成被零除警告,但操作結果爲NULL。
NO_AUTO_CREATE_USER 防止GRANT自動創建新用戶,除非還指定了密碼。
NO_ENGINE_SUBSTITUTION 如果需要的存儲引擎被禁用或未編譯,那麼拋出錯誤。不設置此值時,用默認的存儲引擎替代,並拋出一個異常。

設置

形式如
mysql> set sql_mode='';
mysql> set global.sql_mode='NO_ENGINE_SUBSTITUTION,STRICT_TRANS_TABLES';
或者替換ONLY_FULL_GROUP_BY爲''
set @@session.sql_mode=(select replace(@@session.sql_mode,'ONLY_FULL_GROUP_BY','')); 

不啓用ONLY_FULL_GROUP_BYSQL模式使用Group_by 數據是怎麼獲取的?

官方是這樣解釋的
image.png
簡翻重點:服務器可以從每個組中自由選擇任何值 ;

自己試驗一下
模擬數據

INSERT INTO `group_by_test`
(`id`, `field_one`, `field_two`, `field_three`) 
VALUES 
(1, '1', '', '3-1'),
(2, '1', '2-2', '3-2'),
(3, '1', '2-3', '3-3'),
(4, '1', '', '3-4'),
(5, '1', '2-5', '');

模擬結果:非GROUP BY 子句列,默認取的第一行數據填充
image.png

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章