報(bào)錯(cuò)原因
使用GROUP BY 語(yǔ)句違背了sql_mode=only_full_group_by,在MySQL數(shù)據(jù)庫(kù)版本為5.7以上的版本,默認(rèn)開啟了 ONLY_FULL_GROUP_BY SQL模式,在此模式下,對(duì)于group by操作,如果在select語(yǔ)句中的查詢列沒有在group by中出現(xiàn),那么這個(gè)SQL就是非法的,因?yàn)榱胁辉趃roup by語(yǔ)句中,所以設(shè)置了sql_mode=only_full_group_by的數(shù)據(jù)庫(kù),在使用group by時(shí)就會(huì)報(bào)錯(cuò),換句話說,拒絕選擇列表、HAVING 條件或 ORDER BY 列表引用非聚合列的查詢,這些列既不在 GROUP BY 子句中命名,也不在功能上依賴于(唯一確定的)GROUP BY 列。
注意
不是說SELECT xx,xx必須是GROUP BY中的列,如SELECT 聚集函數(shù)(不在GROUP中的列)也能正常執(zhí)行
例如
現(xiàn)有兩表Student表以及SC表(選課表)。
執(zhí)行語(yǔ)句
select cno,count(sc.sno),count(student.sno) from student,sc group by cno;
紅色部分可以發(fā)現(xiàn)sc.sno與studen.sno都沒有在GROUP BY的列中,但執(zhí)行語(yǔ)句依舊正常,因?yàn)槭褂昧司奂瘮?shù)。
而不把sc.sno放在聚集函數(shù)中,則執(zhí)行錯(cuò)誤。
select cno,sc.sno from student,sc group by cno;
解決方法
臨時(shí)解決(重啟mysqld后失效)
1.直接在mysql-cli層面做設(shè)置
select @@global.sql_mode;
2.將ONLY_FULL_GROUP_BY從sql_mode中移除:
set @@global.sql_mode ='STRICT_TRANS_TABLES,NO_ZERO_IN_DATE,NO_ZERO_DATE,ERROR_FOR_DIVISION_BY_ZERO,NO_ENGINE_SUBSTITUTION';
3.重啟MySQL客戶端
注意不要關(guān)閉mysqld,否則修改會(huì)復(fù)原。
在MySQL-server層面修改sql_mode
永久生效,重啟依然有效
優(yōu)化mysql語(yǔ)句
使用派生表查詢
例子
BOOKSTORAGE表:
存書(書號(hào),書名,出版社,版次,出版日期,作者,書價(jià),進(jìn)價(jià),數(shù)量)
CREATE TABLE BOOKSTORAGE(
isbn VARCHAR(10) PRIMARY KEY,
name VARCHAR(10) NOT NULL,
publisher VARCHAR(10),
edition VARCHAR(10),
date DATE,
writer VARCHAR(10),
price FLOAT CHECK(price>=0),
pprice FLOAT CHECK(pprice>=0),
number INT CHECK(number>=0)
);
銷售(日期,書號(hào),數(shù)量,單價(jià))
CREATE TABLE SALE(
date DATE,
isbn VARCHAR(10),
number INT CHECK(number>=0),
price FLOAT CHECK(price>=0),
FOREIGN KEY(isbn) REFERENCES BOOKSTORAGE(isbn)
);
注意先建立BOOKSTORAGE表再建立SALE表,因?yàn)镾ALE表外鍵參考BOOKSTORAGE,所以要先建立BOOKSTORAGE
插入數(shù)據(jù)
INSERT
INTO BOOKSTORAGE
VALUES('1','西游記','人民文學(xué)出版社','第三版','2003/1/1','吳承恩',20.1,15.5,150),
('2','水滸傳','人民文學(xué)出版社','第二版','2005/9/1','施耐庵',23.9,17.1,200),
('3','三國(guó)演義','中華書局出版社','第五版','2008/6/1','羅貫中',26.3,15.8,210),
('4','紅樓夢(mèng)','人民文學(xué)出版社','第四版','2001/6/1','曹雪芹',22.3,17.2,190);
INSERT
INTO SALE
VALUES('2023-3-12','1','30',17.8),
('2023-3-15','1','20',20.1),
('2023-3-12','2','25',18.8),
('2023-3-15','2','25',23.9),
('2023-3-12','3','15',18.6),
('2023-3-15','3','30',26.3),
('2023-3-12','4','22',19.5),
('2023-3-15','4','12',22.3);
注意先插入BOOKSTORAGE,因?yàn)镾ALE參考BOOKSTORAGE
插入結(jié)果
求解問題
列出所有日期的銷售報(bào)表,包括書名、數(shù)量和合計(jì)金額(每一種書的銷售總金額)
方法1修改sql_mode
mysql語(yǔ)句
SELECT SALE.date,BOOKSTORAGE.name,SALE.number,ROUND(SUM(SALE.price*SALE.number),2) money
FROM SALE,BOOKSTORAGE
WHERE SALE.isbn=BOOKSTORAGE.isbn
GROUP BY SALE.isbn,SALE.DATE
ORDER BY SALE.date;
查詢出所有的sql_mode
select @@global.sql_mode;
移除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';
重啟mysql后,執(zhí)行語(yǔ)句
查詢出所有的sql_mode
發(fā)現(xiàn)沒有ONLY_FULL_GROUP_BY
重啟mysqld后,再次查詢sql_mode
發(fā)現(xiàn)有ONLY_FULL_GROUP_BY
方法2優(yōu)化mysql語(yǔ)句
SELECT SALE2.DATE,name,SALE2.number,SALE2.PRICE
FROM BOOKSTORAGE,(SELECT isbn,date,SUM(number),ROUND(SUM(price*number),2) FROM SALE GROUP BY SALE.isbn,SALE.DATE) AS SALE2(isbn,date,number,price)
WHERE SALE2.isbn=BOOKSTORAGE.isbn
ORDER BY SALE2.DATE ASC;
思考
問題
student表結(jié)構(gòu)
執(zhí)行mysql語(yǔ)句,select 選擇的列不僅僅只有sno,為什么正常輸出?
select * from student group by sno;
文章來源:http://www.zghlxwxcb.cn/news/detail-764659.html
答案
因?yàn)閟no屬性是主碼,即primary key,經(jīng)測(cè)試發(fā)現(xiàn)group by **,**為主碼的屬性名時(shí),select語(yǔ)句中的查詢列沒有在group by中出現(xiàn),也是允許的。文章來源地址http://www.zghlxwxcb.cn/news/detail-764659.html
到了這里,關(guān)于MySQL報(bào)錯(cuò) Expression #2 of SELECT list is not in GROUP BY clause and contains nonaggregated column解決方法的文章就介紹完了。如果您還想了解更多內(nèi)容,請(qǐng)?jiān)谟疑辖撬阉鱐OY模板網(wǎng)以前的文章或繼續(xù)瀏覽下面的相關(guān)文章,希望大家以后多多支持TOY模板網(wǎng)!