日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當前位置: 首頁 > 运维知识 > 数据库 >内容正文

数据库

一文带你了解mysql sql model的only_full_group_by模式含Error 1055问题分析

發布時間:2024/9/27 数据库 22 豆豆
生活随笔 收集整理的這篇文章主要介紹了 一文带你了解mysql sql model的only_full_group_by模式含Error 1055问题分析 小編覺得挺不錯的,現在分享給大家,幫大家做個參考.

? ? ? ? ? ? ?Mysql only_full_group_by及Error 1055問題分析圖解

聲明

本文的數據來自網絡,部分代碼也有所參照,這里做了注釋和延伸,旨在技術交流,如有冒犯之處請聯系博主及時處理。

: 1?員工表結構和數據初始化SQL腳本

? ? ? ? 2??當前驗證環境CentOS 8 X86 64、mysql 8.0.23、SQL Server 2019

問題描述

ERROR 1055 (42000): Expression #1 of SELECT list is not in GROUP BY clause and contains nonaggregated column 'trial.B.dname' which is not functionally dependent on columns in GROUP BY clause; this is incompatible with sql_mode=only_full_group_by

編寫SQL時遇到如下錯誤,即出現錯誤 ERROR 1055,SELECT列表不在GROUP BY語句內且存在不函數依賴GROUP BY語句的非聚合字段'trial.B.dname',這是和sql_mode=only_full_group_by不兼容的(即不支持)。

解決方法

Way 1:臨時關閉only_full_group_by模式,這種方法通過修改系統變量,重啟數據庫后失效(修改后需要新開會話或者窗口)。首先查看下當前的sql_mode:

# 查看mysql當前的sql mode show VARIABLES LIKE 'sql_mode';

-- 1 對系統標量進行全局設置,但數據庫重啟后失效 set global sql_mode='STRICT_TRANS_TABLES,NO_ZERO_IN_DATE,NO_ZERO_DATE,ERROR_FOR_DIVISION_BY_ZERO,NO_ENGINE_SUBSTITUTION'; -- 2 修改后需在新的回話(窗口)里驗證原SQL。

Way 2: 永久關閉only_full_group_by模式,這種方法需要在mysql的配置文件里修改,然后重啟。

Step 1 找到配置文件/etc/my.cnf(或則關聯文件夾找到mysql-server.cnf)

Step 2: 在上述文件內的[mysqld]后追加

sql_mode='STRICT_TRANS_TABLES,NO_ZERO_IN_DATE,NO_ZERO_DATE,ERROR_FOR_DIVISION_BY_ZERO,NO_ENGINE_SUBSTITUTION'

Step 3:保存配置文件后,重啟Mysql即可。

大話group by

啥,這就這么結束?!來來來,別走,我們來拉拉mysql的groupby和sql_mode only_full_group_by模式。開始之前我們得來先做個前期回顧。

SQL 92 group by

首先我們先了解下SQL92標準里關于group by的定義。

SQL-92?and?earlier?does?not?permit?queries?for?which?the?select?list,?HAVING?condition,?or?ORDER?BY?list?refer?to?nonaggregated?columns?that?are?not?named?in?the?GROUP?BY?clause.

簡單的說:SQL-92里 SELECT、HAVING、ORDER后的非聚合字段必須和GROUP BY后的字段保持完全一致。

來個例子瞧瞧唄?如下以sql server2019為例:

--正確的”姿勢” SELECT B.dname,B.deptno,MAX(sal) FROM emp A JOIN dept B ON A.deptno = B.deptno GROUP BY B.deptno,B.dname;--錯誤的“姿勢” SELECT B.dname,B.deptno,MAX(sal) FROM emp A JOIN dept B ON A.deptno = B.deptno GROUP BY B.deptno;

SQL 99 group by

但是我們經常看到MYSQL的SELECT列表的字段并不在GROUP BY后,這又是咋回事?話不多說,先上幾個案例。

-- Msyql: -- Case 1(此腳本在sql server里報錯) SELECT B.deptno,B.dname,MAX(sal) FROM emp A JOIN dept B ON A.deptno = B.deptno GROUP BY B.deptno;

但為什么mysql就能支持呢?

SQL:1999 and later permits such nonaggregates per optional feature T301 if they are functionally dependent on?GROUP BY?columns: If such a relationship exists between?name?and?custid, the query is legal. This would be the case, for example, were?custid?a primary key of?customers.

SQL 99登場,這里即是定義了新的標準,如果group by后面的字段是主鍵(唯一鍵),而且非聚合字段是函數依賴group by后字段的,那么可以將這些非聚合字段放在SELECT、HAVING、ORDER BY的語句之后。

MySQL implements detection of functional dependence. If the?ONLY_FULL_GROUP_BY?SQL mode is enabled (which it is by default), MySQL rejects queries for which the select list,?HAVING?condition, or?ORDER BY?list refer to nonaggregated columns that are neither named in the?GROUP BY?clause nor are functionally dependent on them.

Mysql 實現了這種檢測函數依賴,這時ONLY_FULL_GROUP_BY?SQL 模式登場,mysql里SQL mode設置了這種模式那么如果 group by后的不補全字段或是無函數依賴的字段時非聚合字段放在SELECT、HAVING、ORDER BY的語句之后是不支持的。

有點繞,我們直接開啟個案例來說明ONLY_FULL_GROUP_BY有何魔力。

啟用only_full_group_by模式

-- Case 2: SELECT B.dname,MAX(sal) FROM emp A JOIN dept B ON A.deptno = B.deptno GROUP BY B.loc

原因分析,這里group by后的字段loc并沒有定義為主鍵或則唯一鍵,所以在sql mode是ONLY_FULL_GROUP_BY模式下報錯(即不支持)。

我們再來個簡單些的例子,即只涉及一張表。

-- Case 3: --Step 1 創建一張無主鍵、唯一鍵的表,插入4條記錄(id字段的值不重復)。 CREATE TABLE `test_04251019` (`id` int DEFAULT NULL,`name` varchar(10) DEFAULT NULL,`addr` varchar(12) DEFAULT NULL,`memo` varchar(40) DEFAULT NULL ) ENGINE=InnoDB DEFAULT CHARSET=utf8;-- Step 2 插入4條記錄 INSERT INTO `test_04251019` VALUES ('1', 'hanmeimie', 'Guangzhou', 'Fullbakup'); INSERT INTO `test_04251019` VALUES ('2', 'lilei', 'Guangzhou', 'in increament'); INSERT INTO `test_04251019` VALUES ('4', 'Tom', 'Shanghai', 'no more'); INSERT INTO `test_04251019` VALUES ('5', 'John', 'Shanghai', 'no more_5');-- Step 3 此時我們仿照Case 2寫個簡單點的聚合語句 SELECT name, MAX(LENGTH(addr)) FROM test_04251019 GROUP BY id;

-- Case 4: -- Step 1 創建個表類似(test_04251019),但是id定義為主鍵 CREATE TABLE `test_04251019_key` (`id` int NOT NULL,`name` varchar(10) DEFAULT NULL,`addr` varchar(12) DEFAULT NULL,`memo` varchar(40) DEFAULT NULL, PRIMARY KEY (`id`) ) ENGINE=InnoDB AUTO_INCREMENT=1 DEFAULT CHARSET=utf8;-- Step 2 插入數據(直接拷貝至test_04251019) INSERT INTO test_04251019_key(id,name,addr,memo) SELECT id,name,addr,memo FROM test_04251019; COMMIT;-- Step 3 新增個唯一字段id_2并更新數據 ALTER TABLE test_04251019_key ADD id_2 int NOT NULL; UPDATE test_04251019_key SET id_2 = 100+id; ALTER TABLE test_04251019_key ADD CONSTRAINT unique_id_2 UNIQUE(id_2);-- Step 4 驗證group by后含主鍵、唯一鍵,非聚合字段并存的情況 SELECT name, MAX(LENGTH(addr)) FROM test_04251019_key GROUP BY id; SELECT name, MAX(LENGTH(addr)) FROM test_04251019_key GROUP BY id_2;

關閉only_full_group_by模式

一眼不合,我們就關閉only_full_group_by模式。那么我們就來關閉,這里通過修改系統變量的方式。

-- 通過修改系統變量方式,注意修改后需要在新的回話(重開個客戶端)里驗證 set global sql_mode='STRICT_TRANS_TABLES,NO_ZERO_IN_DATE,NO_ZERO_DATE,ERROR_FOR_DIVISION_BY_ZERO,NO_ENGINE_SUBSTITUTION';show variables like 'sql_mode';

這時我們來驗證Case 2

?Case 3

Case 4:追加案例,針對case 3,如果我們往test_04251019里插入一條記錄

-- 插入一條數據(這里id是重復的,已有等于5的了) INSERT INTO test_04251019 VALUES(5,'Jim','Shanghai2','no more_5_2');-- 再執行聚合函數驗證 SELECT name, MAX(LENGTH(addr)) FROM test_04251019 GROUP BY id;

what?“Jim”那條記錄對應的GROUP BY統計去哪兒了?為啥不能是我?!

延展閱讀

ONLY_FULL_GROUP_BY下的特例(僅有聚合函數和WHERE,這里WHERE是必選項),詳見如下截圖:

總結

敲黑板

  • Mysql里的sql mode=only_full_group_by模式是對SQL92 group by的擴展,即對應SQL1999的標準。
  • SQL92 group by里要求SELECT、HAVING、ORDER BY語句后的字段需要與GROUP BY后的字段嚴格一致。
  • Myslq的sql mode=only_full_group_by模式SELECT、HAVING、ORDER BY語句后的字段可以不跟GROUP BY后的字段嚴格一致,但是GROUP BY的字段需是主鍵或唯一鍵時可以寫非聚合字段。
  • Myslq的sql mode非only_full_group_by模式時在表的定義不嚴格的情況下(如無明確的主鍵且數據重復時作為GROUP BY后的字段 )執行結果難以解釋。
  • 更多詳細細節,詳見官網Mannul。
  • Any question let me know.
  • 總結

    以上是生活随笔為你收集整理的一文带你了解mysql sql model的only_full_group_by模式含Error 1055问题分析的全部內容,希望文章能夠幫你解決所遇到的問題。

    如果覺得生活随笔網站內容還不錯,歡迎將生活随笔推薦給好友。