自拍偷在线精品自拍偷,亚洲欧美中文日韩v在线观看不卡

孤陋寡聞了,原來 MySQL 還能這么寫?

數(shù)據(jù)庫 MySQL
建議沒有特殊情況,還是打開ONLY_FULL_GROUP_BY,這樣能保證你的查詢結(jié)果不會因為你寫錯 SQL 而出現(xiàn)莫名奇妙的數(shù)據(jù),數(shù)據(jù)庫會及時給你拋出錯誤,避免你對著一串 SQL 查錯時一面懵。

最近給一個我從來沒碰過的老系統(tǒng)加點兒功能,本來連測試環(huán)境的數(shù)據(jù)庫一切都很順利,但是為了保證功能在生產(chǎn)數(shù)據(jù)上沒有問題,就準(zhǔn)備把一部分生產(chǎn)數(shù)據(jù)搞到我本地環(huán)境上測一下。

結(jié)果,果然出現(xiàn)了問題,代碼問題就是這樣,總在不經(jīng)意間來到。

依我我知,想要不出現(xiàn)代碼問題,最好的方式就是——不寫代碼!

出現(xiàn)問題,咱就解決啊,我一看日志控制臺一大堆紅色報錯,不對啊,這都不是我剛加的功能報出來的,這樣的話,我就放心了。

摘出來一條錯誤信息是下面這樣的,是 SQL 查詢語句報錯了,報錯信息很明顯,就是說GROUP BY 后面的條件沒有在前面的 SELECT Columns 列表里。

一看其中有兩個關(guān)鍵點:

  1. GROUP BY
  2. sql_mode=only_full_group_by
1055 - Expression #2 of SELECT list is not in GROUP BY clause and contains nonaggregated column 'c.type' which is not functionally dependent on columns in GROUP BY clause; this is incompatible with sql_mode=only_full_group_by, Time: 0.001000s

我把 SQL 簡化了一下就是下面這個樣子:

select u.id,u.age from user u GROUP BY u.province;

一看這條 SQL,我心想,這SQL 本身就有問題啊,怎么就在系統(tǒng)中呆了這么長時間,但是在測試和生產(chǎn)環(huán)境確實就是正常運行的。

我本地一直用MySQL5.7,再看測試和生產(chǎn)數(shù)據(jù)庫,也是 5.7,就是小版本不太一樣,按往常經(jīng)驗,小版本應(yīng)該不會有這么大影響。

那肯定就是配置的問題,那肯定就是報錯信息中提到的 sql_mode=only_full_group_by 這個,原諒我孤陋寡聞了,用了 MySQL 這么久,從來沒聽過這玩意,而且用 GROUP BY就是為了分組聚合,GROUP BY后面的條件要出現(xiàn)在 SELECT 列表里不是很正常嗎,除非有兩個列有同樣的作用,比如一個名稱,一個編碼,用編碼分組,顯示名稱。要不然分組的意義在哪里呢?

但是系統(tǒng)已經(jīng)運行了很長時間了,那這 SQL 一定有他存在的意義,不管那么多了,看問題就好了。

sql_mode

然后我給自己科普了一下 sql_mode。

sql_mode 是 MySQL 的一個系統(tǒng)變量,用來控制 MySQL 服務(wù)器的 SQL 語法和行為的處理方式。通過配置不同的 sql_mode 值,MySQL 可以在 SQL 語法檢查、數(shù)據(jù)完整性約束、以及查詢處理等方面進(jìn)行不同的操作。

總之,就是 MySQL 會根據(jù)這個配置的內(nèi)容,來靈活的進(jìn)行語法檢查、數(shù)據(jù)約束等操作,加入的變量越多,控制的就越嚴(yán)格。

發(fā)現(xiàn)從 MySQL 5.7 開始,sql_mode 加了很多變量,ONLY_FULL_GROUP_BY就在其中。

使用 SELECT @@sql_mode;可以查詢數(shù)據(jù)庫中 sql_mode 配置的變量有哪些,這是 5.7 版本的默認(rèn)配置。

ONLY_FULL_GROUP_BY,STRICT_TRANS_TABLES,NO_ZERO_IN_DATE,NO_ZERO_DATE,ERROR_FOR_DIVISION_BY_ZERO,NO_AUTO_CREATE_USER,NO_ENGINE_SUBSTITUTION

既然是變量,就是可以改的,所以,這些變量可以動態(tài)的增減,或者索性全部去掉。

那肯定就是測試和生產(chǎn)環(huán)境改了這個配置了,上去一查,果不其然,那叫一個干凈。后來問之前的同事,了解到之前用的是更早的 MySQL 版本,后來統(tǒng)一升級到了 5.7,然后發(fā)現(xiàn)這個問題,所以改了配置。

ONLY_FULL_GROUP_BY

別的不說,只說 ONLY_FULL_GROUP_BY,當(dāng)數(shù)據(jù)庫中啟用了 ONLY_FULL_GROUP_BY 模式后,就要求在 GROUP BY 查詢中,SELECT 子句中的每一列都必須要么出現(xiàn)在 GROUP BY 子句中,要么應(yīng)用聚合函數(shù)(如 COUNT()、SUM()、MAX()、MIN() 等)。

這個例子中就是,province這個字段沒有在前面 SELECT 的字段列表中。我從剛用 MySQL 時一直都是按照 GROUP BY后面的列必須在前面的查詢列中來做的,沒想到這個還能改。

select u.id,u.age from user u GROUP BY u.province;

這種不行,下面這個也不行,因為 SELECT 查詢列表中的 u.id 不在 GROUP BY 后面的條件中

select u.id,u.age from user u GROUP BY u.age;

改成下面這樣才行

select u.id,u.age from user u GROUP BY u.age,u.id;
--  或者
select u.age from user u GROUP BY u.age;

或者,還有一種情況,可以允許 SELECT 中存在 GROUP BY 后面沒有的列,就是加 聚合函數(shù)。

這應(yīng)該是最常規(guī)的用法了。

select max(u.id),u.age from user u GROUP BY u.age;

除了影響 GROUP BY外,還會影響 ORDER BY,看下面這條語句,當(dāng)開啟 ONLY_FULL_GROUP_BY后,會報錯

SELECT DISTINCT
	b.title,
	b.create_time 
FROM
	b_user b 
ORDER BY
	b.create_time DESC,
	b.update_time DESC

報錯信息:

1064 - You have an error in your SQL syntax; check the manual that corresponds to your MySQL server version for the right syntax to use near 'b.update_time DESC' at line 24, Time: 0.001000s

因為update_time字段不在 SELECT 后面,當(dāng)然這還是因為加了 DISTINCT。當(dāng)關(guān)閉 ONLY_FULL_GROUP_BY后,就能正常執(zhí)行了。

關(guān)閉 ONLY_FULL_GROUP_BY 模式

如果真的碰到從低版本升級上來的,系統(tǒng)中有很多這樣不符合  ONLY_FULL_GROUP_BY規(guī)范的語句,最省事的辦法就是直接關(guān)掉。

最省事兒的方法就是直接改 MySQL 配置文件,找到my.cnf配置文件,將其中的 sql_mode 改成下面這樣

sql_mode = ""

然后重啟就好了。

最后

建議沒有特殊情況,還是打開ONLY_FULL_GROUP_BY,這樣能保證你的查詢結(jié)果不會因為你寫錯 SQL 而出現(xiàn)莫名奇妙的數(shù)據(jù),數(shù)據(jù)庫會及時給你拋出錯誤,避免你對著一串 SQL 查錯時一面懵。

除非你能明確地知道你為什么需要把 ONLY_FULL_GROUP_BY關(guān)掉。

責(zé)任編輯:武曉燕 來源: 古時的風(fēng)箏
相關(guān)推薦

2021-08-29 18:13:03

緩存失效數(shù)據(jù)

2022-01-04 08:00:48

前端技術(shù)Esbuild

2021-12-30 10:55:54

Python游戲腳本

2022-01-27 14:12:49

Python游戲腳本

2010-01-20 10:37:48

Chrome瀏覽器

2019-12-30 09:51:35

Word設(shè)計模式軟件

2018-01-25 14:53:20

iPhone技巧刪除照片

2022-02-14 21:58:58

netstatLinuxWindows

2021-04-19 05:42:51

Mmap文件系統(tǒng)

2022-06-01 07:49:43

索引數(shù)據(jù)Mysql

2021-08-02 08:22:50

MySQL 分庫分表

2023-11-01 14:49:07

2022-10-31 08:47:21

人臉識別按鍵鍵盤

2020-07-29 10:00:13

MySQL雙主架構(gòu)數(shù)據(jù)庫

2021-08-20 15:43:54

iPhone手機iOS

2023-05-07 23:22:24

golang

2017-03-17 13:40:48

思科視頻

2020-05-09 16:45:56

ping命令Linux

2022-12-06 17:30:04

2022-10-21 08:17:13

MongoDB查詢Document
點贊
收藏

51CTO技術(shù)棧公眾號