ข้อผิดพลาดที่เกี่ยวข้องกับ only_full_group_by เมื่อดำเนินการค้นหาใน MySql


442

ฉันได้อัพเกรดระบบของฉันและได้ติดตั้ง MySql 5.7.9 ด้วย php สำหรับเว็บแอปพลิเคชันที่ฉันกำลังทำงานอยู่ ฉันมีคิวรีที่สร้างขึ้นแบบไดนามิกและเมื่อทำงานใน MySql เวอร์ชันเก่ามันทำงานได้ดี ตั้งแต่อัปเกรดเป็น 5.7 ฉันได้รับข้อผิดพลาดนี้:

นิพจน์ # 1 ของรายการที่เลือกไม่ได้อยู่ในกลุ่มตามข้อและมีคอลัมน์ที่ไม่รวม 'support_desk.mod_users_groups.gid_id' ซึ่งไม่ได้ขึ้นอยู่กับหน้าที่ของคอลัมน์ในกลุ่มตามข้อ; สิ่งนี้เข้ากันไม่ได้กับ sql_mode = only_full_group_by

หมายเหตุ: หน้าคู่มือสำหรับ MySQL 5.7 ในหัวข้อของโหมด SQL Server

นี่คือแบบสอบถามที่ทำให้ฉันมีปัญหา:

SELECT mod_users_groups.group_id AS 'value', 
       group_name AS 'text' 
FROM mod_users_groups
LEFT JOIN mod_users_data ON mod_users_groups.group_id = mod_users_data.group_id 
WHERE  mod_users_groups.active = 1 
  AND mod_users_groups.department_id = 1 
  AND mod_users_groups.manage_work_orders = 1 
  AND group_name != 'root' 
  AND group_name != 'superuser' 
GROUP BY group_name 
HAVING COUNT(`user_id`) > 0 
ORDER BY group_name

ฉันทำ googling เกี่ยวกับปัญหานี้ แต่ฉันไม่เข้าใจonly_full_group_byพอที่จะเข้าใจว่าฉันต้องทำอะไรเพื่อแก้ไขแบบสอบถาม ฉันสามารถปิดonly_full_group_byตัวเลือกหรือมีสิ่งอื่นที่ฉันต้องทำหรือไม่

แจ้งให้เราทราบหากคุณต้องการข้อมูลเพิ่มเติม


ที่นี่ฉันพบโซลูชันstackoverflow.com/a/7588442/612987
Wasim A.

21
นี่เป็นข้อความแสดงข้อผิดพลาดที่ซับซ้อนที่สุดที่ฉันเคยเจอ
Rolf

2
@Rolf คุณเคยเห็นข้อผิดพลาดสำหรับปัญหาประเภทเดียวกันใน Oracle หรือไม่? " not a GROUP BY expression" แค่นั้นแหละ พวกเขาก็อาจมีรหัสข้อผิดพลาดเป็นตัวเลขและไม่มีข้อความเลย
Bill Karwin

คำตอบ:


359

ฉันเพิ่งจะเพิ่มไปgroup_idGROUP BY

เมื่อไหร่ SELECT ing คอลัมน์ที่ไม่ได้เป็นส่วนหนึ่งGROUP BYอาจมีหลายค่าสำหรับคอลัมน์นั้นภายในกลุ่ม แต่จะมีที่ว่างสำหรับค่าเดียวในผลลัพธ์ ดังนั้นฐานข้อมูลมักจะต้องมีการบอกวิธีการทำให้ค่าหลายค่าเหล่านั้นเป็นค่าเดียว ปกตินี้จะทำกับฟังก์ชันการรวมเช่นCOUNT(), SUM(), MAX()ฯลฯ ... ผมบอกว่ามักจะเพราะอื่น ๆ ส่วนใหญ่ที่นิยมระบบฐานข้อมูลยืนยันเกี่ยวกับเรื่องนี้ อย่างไรก็ตามใน MySQL ก่อนหน้ารุ่น 5.7 พฤติกรรมเริ่มต้นได้รับการให้อภัยมากขึ้นเพราะมันจะไม่บ่นแล้วเลือกค่าใด ๆ ! นอกจากนี้ยังมีANY_VALUE()ฟังก์ชั่นที่สามารถใช้เป็นวิธีแก้ปัญหาอื่นสำหรับคำถามนี้หากคุณต้องการพฤติกรรมที่เหมือนเดิม ความยืดหยุ่นนี้มาพร้อมกับราคาเพราะไม่ได้กำหนดไว้ดังนั้นฉันจะไม่แนะนำถ้าคุณมีเหตุผลที่ดีมากสำหรับความต้องการ ขณะนี้ MySQL กำลังเปิดการonly_full_group_byตั้งค่าตามค่าเริ่มต้นด้วยเหตุผลที่ดีดังนั้นจึงเป็นการดีที่สุดที่จะทำความคุ้นเคยและทำให้แบบสอบถามของคุณสอดคล้องกับมัน

ดังนั้นทำไมคำตอบง่ายๆของฉันด้านบน ฉันได้ตั้งสมมติฐานไว้สองสามข้อ:

1) ความgroup_idเป็นเอกลักษณ์ ดูเหมือนว่ามันเป็น 'ID' หลังจากทั้งหมด

2) group_nameยังเป็นเอกลักษณ์ นี่อาจไม่ใช่ข้อสมมติฐานที่สมเหตุสมผล ถ้ากรณีนี้ไม่ได้และคุณมีซ้ำกันบางgroup_namesและคุณจากนั้นทำตามคำแนะนำของฉันที่จะเพิ่มgroup_idไปที่GROUP BYคุณอาจพบว่าตอนนี้คุณจะได้รับผลมากขึ้นกว่าก่อนเพราะกลุ่มที่มีชื่อเดียวกันในขณะนี้จะมีแถวแยกต่างหากในผลลัพธ์ สำหรับฉันแล้วนี่จะดีกว่าการซ่อนกลุ่มที่ซ้ำกันเหล่านี้เพราะฐานข้อมูลได้เลือกค่าอย่างเงียบ ๆ !

นอกจากนี้ยังเป็นการดีที่จะกำหนดคอลัมน์ทั้งหมดด้วยชื่อตารางหรือชื่อแทนเมื่อมีมากกว่าหนึ่งตารางที่เกี่ยวข้อง ...

SELECT 
  g.group_id AS 'value', 
  g.group_name AS 'text' 
FROM mod_users_groups g
LEFT JOIN mod_users_data d ON g.group_id = d.group_id 
WHERE g.active = 1 
  AND g.department_id = 1 
  AND g.manage_work_orders = 1 
  AND g.group_name != 'root' 
  AND g.group_name != 'superuser' 
GROUP BY 
  g.group_name, 
  g.group_id 
HAVING COUNT(d.user_id) > 0 
ORDER BY g.group_name

ขอบคุณที่ใช้งานได้ดี ฉันยอมรับด้วยว่าฉันต้องผ่านการรับรองคอลัมน์ มันกำจัดความเป็นไปได้ของความคลุมเครือใด ๆ ฉันอยู่ระหว่างการซ่อมแซมรหัสในขณะนี้ ขอบคุณหนึ่งล้านสำหรับความช่วยเหลือ
Dan Bemowski

ฉันไม่ได้มีGROUP BYข้อในแบบสอบถามของฉัน แต่ฉันได้รับข้อผิดพลาดนี้
aitchkhan

@HaroonKhan ที่ดูเหมือนคำถามใหม่ แจ้งให้เราทราบหากคุณถาม & ฉันจะดู
davmos

2
ใน MySQL 5.7 พวกเขาตั้งค่าคุณสมบัติที่ต้องการเขตข้อมูลที่ไม่รวมทั้งหมดในแบบสอบถามเป็น GROUP BY ดังนั้นแบบสอบถามเช่น SELECT a, SUM (b) FROM ตาราง; หมายความว่าฟิลด์ "a" ต้องอยู่ในกลุ่มตาม ดังนั้นหากคุณไม่มี GROUP BY คุณจะต้องเพิ่มเข้าไปในแบบสอบถาม มันคือทั้งหมดที่เกี่ยวกับถ้าคุณมีอย่างน้อยหนึ่งเขตข้อมูลรวมในส่วนที่เลือกของแบบสอบถามของคุณ
user1567291

ฉันต้องแก้ไข "คำเตือน" โดยเพิ่มรายการไปยังกลุ่มตามข้อแนะนำในคำตอบนี้เพราะไม่มีคำตอบที่แนะนำ sql_mode แก้ไขทำงาน (MySQL ของฉันอยู่ในขั้นตอนการเก็บ แต่ไม่ทราบว่าเป็นที่เกี่ยวข้อง)
zzapper

355

คุณสามารถลองปิดการใช้งานการonly_full_group_byตั้งค่าโดยดำเนินการต่อไปนี้:

mysql> set global sql_mode='STRICT_TRANS_TABLES,NO_ZERO_IN_DATE,NO_ZERO_DATE,ERROR_FOR_DIVISION_BY_ZERO,NO_AUTO_CREATE_USER,NO_ENGINE_SUBSTITUTION';
mysql> set session sql_mode='STRICT_TRANS_TABLES,NO_ZERO_IN_DATE,NO_ZERO_DATE,ERROR_FOR_DIVISION_BY_ZERO,NO_AUTO_CREATE_USER,NO_ENGINE_SUBSTITUTION';

MySQL 8 ไม่ยอมรับNO_AUTO_CREATE_USERดังนั้นจำเป็นต้องลบออก


85
นี่คือการแก้ไขคุณควรแก้ไขแบบสอบถามของคุณให้ดีกว่าที่จะห้ามไม่ให้มีการเตือน
azerafati

1
การอัพเดต /etc/mysql/my.cnf (ดังที่แสดงด้านล่าง) เป็นวิธีแก้ปัญหาที่ยั่งยืนกว่าเนื่องจากการตั้งค่าเริ่มต้นมักจะกลับมาหลังจากรีสตาร์ท และสำหรับผู้ที่กล่าวว่าคุณควรแก้ไขแบบสอบถามบางครั้งก็ไม่ใช่เรื่องง่ายเมื่อคุณต้องการสอบถามแก้จุดบกพร่องอย่างรวดเร็วและทำสิ่งต่าง ๆ เช่นSELECT COUNT(*), t.* FROM my_table t GROUP BY colและคุณมี 20-50 คอลัมน์คุณต้องการใช้เวลามากในการเพิ่มแต่ละคอลัมน์ใน จัดกลุ่มตาม
Shadoweb

3
"ทางออก" นี้ค่อนข้างอันตราย คุณสามารถเปิดใช้งานโหมดที่คุณปิดใช้งานไว้ก่อนหน้านี้โดยการเปลี่ยนโหมดแบบสุ่มสี่สุ่มห้าแทนการลบการตั้งค่าเดียวที่เป็นปัญหา สิ่งนี้อาจนำไปสู่พฤติกรรมที่ไม่คาดคิดและในกรณีที่เลวร้ายที่สุดนำไปสู่ผลลัพธ์ที่ไม่ถูกต้องหรือหยุดแอปของคุณไม่ให้ทำงานโดยสิ้นเชิง ดังนั้นฉันคิดว่าคำตอบนี้ผิด
Chris S.

1
ฉันทำสิ่งนี้อย่างต่อเนื่องผ่านการรีเฟรชโดยหา sql_mode ปัจจุบันของฉันผ่านทางSELECT @@sql_mode;แล้วเพิ่มผลลัพธ์จากที่นั่นไปยัง my.cnf:sql_mode=[list of modes from query, minus ONLY_FULL_GROUP_BY]
wbharding

323

คุณสามารถปิดข้อความเตือนตามที่อธิบายไว้ในคำตอบอื่น ๆ หรือคุณสามารถเข้าใจสิ่งที่เกิดขึ้นและแก้ไขได้

ในฐานะของ MySQL 5.7.5 โหมดเริ่มต้นของ SQL รวมถึง ONLY_FULL_GROUP_BYซึ่งหมายความว่าเมื่อคุณจัดกลุ่มแถวแล้วเลือกบางอย่างจากกลุ่มนั้นคุณต้องระบุอย่างชัดเจนว่าควรเลือกแถวใด Mysql จำเป็นต้องรู้ว่าแถวใดในกลุ่มที่คุณกำลังค้นหาซึ่งมีตัวเลือกให้คุณสองแบบ

Mysql จำเป็นต้องรู้ว่าแถวใดในกลุ่มที่คุณกำลังค้นหาซึ่งมีตัวเลือกให้คุณสองแบบ

  • คุณยังสามารถเพิ่มคอลัมน์ที่คุณต้องการให้กับคำสั่งกลุ่มgroup by rect.color, rect.valueซึ่งอาจเป็นสิ่งที่คุณต้องการในบางกรณีมิฉะนั้นจะส่งคืนผลลัพธ์ที่ซ้ำกันด้วยสีเดียวกันซึ่งคุณอาจไม่ต้องการ
  • คุณสามารถใช้ฟังก์ชันการรวมของ mysql เพื่อระบุแถวที่คุณต้องการภายในกลุ่มเช่นAVG() MIN() MAX() รายการที่สมบูรณ์
  • และในที่สุดคุณสามารถใช้ANY_VALUE()หากคุณแน่ใจว่าผลลัพธ์ทั้งหมดในกลุ่มเหมือนกัน คุณหมอ

25
ฉันไม่คิดว่า MySQL รองรับFIRST()เมธอด / ฟังก์ชั่นใช่หรือไม่
Ben Guild

3
ฉันเชื่อว่า MySQL (อย่างน้อยก่อนถึง 5.7) จะใช้ค่าเริ่มต้นเป็นค่าแรกที่พบในกลุ่ม ดังนั้นจึงไม่มี FIRST () เพราะเคยมีความหมายเหมือนกันกับฟังก์ชัน GROUP BY
DrDamnit

2
@DrDamnit ผมเชื่อว่ามันได้มากขึ้นเช่นการสุ่มเลือกในกรณีดังกล่าวซึ่งนำไปสู่ความสับสนและจึงทำให้ONLY_FULL_GROUP_BYโดยค่าเริ่มต้น
azerafati

6
ฉันรู้คำตอบอยู่แล้ว แต่ตัวอย่างที่มีรูปสี่เหลี่ยมผืนผ้าสีนั้นง่ายต่อการเข้าใจฉันจะใช้ซ้ำในครั้งต่อไปที่มีคนถามฉันเกี่ยวกับเรื่องนี้
user327961

@azerafati มีบางอย่างเช่น FIRST () หรือข้อความค้นหาบางอย่างที่สามารถใช้เพื่อรับค่าแรกเป็นกรณีของฉัน
Haris

169

หากคุณไม่ต้องการทำการเปลี่ยนแปลงใด ๆ ในแบบสอบถามปัจจุบันของคุณให้ทำตามขั้นตอนด้านล่าง -

  1. SSH คนจรจัดเข้าไปในกล่องของคุณ
  2. ประเภท: sudo vim /etc/mysql/my.cnf
  3. เลื่อนไปที่ด้านล่างของไฟล์และพิมพ์Aเพื่อเข้าสู่โหมดแทรก
  4. คัดลอกและวาง

    [mysqld]
    sql_mode = STRICT_TRANS_TABLES,NO_ZERO_IN_DATE,NO_ZERO_DATE,ERROR_FOR_DIVISION_BY_ZERO,NO_AUTO_CREATE_USER,NO_ENGINE_SUBSTITUTION
  5. พิมพ์escเพื่อออกจากโหมดป้อนข้อมูล

  6. พิมพ์:wqเพื่อบันทึกและปิดกลุ่ม
  7. พิมพ์sudo service mysql restartเพื่อเริ่ม MySQL ใหม่

ผู้ใช้งาน Vagrant ทุกคนที่พยายามใช้สิ่งนี้กับ AdonisJS คุณต้องการสิ่งนี้เพื่อเรียกใช้paginateฟังก์ชัน
Michael J. Calkins

เห็นได้ชัดว่าไม่เพียง แต่สำหรับผู้ใช้ Vagrant แต่ระบบ Unix ใด ๆ โปรดทราบว่าสำหรับฉันที่ตั้งของไฟล์เป็นmy.cnf /etcอัลโน้ตไวยากรณ์ใหม่ตั้งแต่MySQL 5.7.8: sql-mode="STRICT_TRANS_TABLES,NO_ZERO_IN_DATE,NO_ZERO_DATE,ERROR_FOR_DIVISION_BY_ZERO,NO_AUTO_CREATE_USER,NO_ENGINE_SUBSTITUTION"
Valentin Grégoire

ได้ผลสำหรับฉันในโรงกษาปณ์ 19.3 (Ubuntu 18.04) ขอบคุณ
Marco López

71

ใช้ANY_VALUE()เพื่ออ้างถึงคอลัมน์ที่ไม่รวม

SELECT name,           address , MAX(age) FROM t GROUP BY name; -- fails
SELECT name, ANY_VALUE(address), MAX(age) FROM t GROUP BY name; -- works

จากMySQL 5.7 เอกสาร :

คุณสามารถได้รับผลกระทบเดียวกันโดยไม่ปิดใช้งานONLY_FULL_GROUP_BY โดยใช้ANY_VALUE()เพื่ออ้างถึงคอลัมน์ที่ไม่รวม

...

แบบสอบถามนี้อาจไม่ถูกต้องเมื่อONLY_FULL_GROUP_BYเปิดใช้งานเนื่องจากคอลัมน์ที่อยู่ที่ไม่รวมในรายการที่เลือกไม่มีชื่ออยู่ในส่วนGROUP BYคำสั่ง:

SELECT name, address, MAX(age) FROM t GROUP BY name;

...

หากคุณรู้ว่าสำหรับชุดข้อมูลที่กำหนดแต่ละค่าชื่อในความเป็นจริงจะกำหนดค่าที่อยู่อย่างไม่ซ้ำกันที่อยู่นั้นขึ้นอยู่กับการทำงานอย่างมีประสิทธิภาพขึ้นอยู่กับชื่อ เพื่อบอกให้ MySQL ยอมรับการสืบค้นคุณสามารถใช้ANY_VALUE()ฟังก์ชัน:

SELECT name, ANY_VALUE(address), MAX(age) FROM t GROUP BY name;

1
ในฐานะที่เป็นคนที่เคยประสบปัญหานี้มาระยะหนึ่งแล้วฉันชอบโซลูชันนี้เป็นพิเศษเพราะมันไม่ต้องการให้คุณเปลี่ยนไฟล์หรือการตั้งค่าใด ๆ ในการตั้งค่า MySQL ของคุณ ที่น่าสนใจพอฉันไม่เห็นการANY_VALUE พูดถึงที่อื่นในการสนทนาที่คล้ายกัน - ทำงานได้อย่างสมบูรณ์แบบสำหรับฉันด้วยความGROUP_BY contains nonaggregated columnผิดพลาดของฉัน
adstwlearn

50

ฉันจะพยายามอธิบายให้คุณทราบว่าข้อผิดพลาดนี้เกี่ยวกับอะไร
เริ่มจาก MySQL 5.7.5 ตัวเลือกONLY_FULL_GROUP_BYจะเปิดใช้งานตามค่าเริ่มต้น
ดังนั้นตามมาตรฐาน SQL92 และที่เก่ากว่า:

ไม่อนุญาตการสืบค้นที่รายการที่เลือกเงื่อนไขการมีหรือรายการเรียงลำดับตามอ้างถึงคอลัมน์ที่ไม่รวมที่ไม่ได้ตั้งชื่อในส่วน GROUP BY clause หรือขึ้นอยู่กับการใช้งาน (ขึ้นอยู่กับคอลัมน์) GROUP BY

( อ่านเพิ่มเติมในเอกสาร )

ตัวอย่างเช่น:

SELECT * FROM `users` GROUP BY `name`;

คุณจะได้รับข้อความแสดงข้อผิดพลาดหลังจากดำเนินการแบบสอบถามด้านบน

# 1055 - นิพจน์ # 1 ของรายการที่เลือกไม่ได้อยู่ในกลุ่มตามข้อและมีคอลัมน์ที่ไม่รวมตัวกัน 'testsite.user.id' ซึ่งไม่ได้ขึ้นอยู่กับหน้าที่ในการใช้งานคอลัมน์ในกลุ่มตามข้อ; สิ่งนี้เข้ากันไม่ได้กับ sql_mode = only_full_group_by

ทำไม?
เนื่องจาก MySQL ไม่เข้าใจอย่างชัดเจนว่ามีค่าใดบ้างจากการจัดกลุ่มระเบียนเพื่อดึงข้อมูลและนี่คือประเด็น

IE บอกว่าคุณมีบันทึกนี้ในusersตารางของคุณ:
โย่

และคุณจะดำเนินการค้นหาที่ไม่ถูกต้องแสดงด้านบน
และคุณจะได้รับข้อผิดพลาดที่แสดงด้านบนเนื่องจากมี 3 เร็กคอร์ดที่มีชื่อJohnและเป็นสิ่งที่ดี แต่ทั้งหมดนั้นมีemailค่าฟิลด์ต่างกัน
ดังนั้น MySQL ก็ไม่เข้าใจว่าพวกเขาคนไหนที่กลับมาเป็นกลุ่ม

คุณสามารถแก้ไขปัญหานี้ได้โดยเพียงเปลี่ยนการค้นหาของคุณเช่นนี้:

SELECT `name` FROM `users` GROUP BY `name`

นอกจากนี้คุณอาจต้องการเพิ่มเขตข้อมูลเพิ่มเติมลงในส่วน SELECT แต่คุณไม่สามารถทำได้หากไม่รวม แต่มี crutch ที่คุณสามารถใช้ (แต่ไม่แนะนำให้สูง):

SELECT ANY_VALUE(`id`), ANY_VALUE(`email`), `name` FROM `users` GROUP BY `name`

ป้อนคำอธิบายรูปภาพที่นี่

ตอนนี้คุณอาจถามว่าทำไมANY_VALUEไม่แนะนำให้ใช้อย่างสูง
เนื่องจาก MySQL ไม่ทราบว่าค่าใดของระเบียนที่จัดกลุ่มเพื่อเรียกคืนและโดยใช้ฟังก์ชันนี้คุณจึงขอให้ดึงข้อมูลใด ๆ ของพวกเขา (ในกรณีนี้อีเมลของระเบียนแรกที่มีชื่อ = John ถูกเรียก)
ฉันไม่สามารถหาแนวความคิดเกี่ยวกับสาเหตุที่คุณต้องการให้พฤติกรรมนี้มีอยู่จริง

กรุณาถ้าคุณไม่เข้าใจฉันอ่านเพิ่มเติมเกี่ยวกับวิธีการจัดกลุ่มใน MySQL มันง่ายมาก

และในตอนท้ายนี่คือแบบสอบถามที่เรียบง่าย แต่มีประโยชน์มากกว่า
หากคุณต้องการสอบถามผู้ใช้ทั้งหมดนับตามอายุที่มีอยู่คุณอาจต้องการเขียนแบบสอบถามนี้

SELECT `age`, COUNT(`age`) FROM `users` GROUP BY `age`;

ซึ่งใช้ได้อย่างสมบูรณ์ตามกฎ MySQL
และอื่น ๆ

เป็นสิ่งสำคัญที่จะต้องเข้าใจว่าปัญหาคืออะไรและเพียงแค่เขียนวิธีการแก้ปัญหา


ขอบคุณสำหรับคำตอบที่ดีนี้ จะทำอย่างไรถ้าฉันต้องการอีเมลด้วยในฐานะอาร์เรย์ในกลุ่มผลลัพธ์
โยสิยาห์

1
คุณสามารถ GROUP_CONCAT ฟิลด์ที่จำเป็นเพื่อรับทุกรายการ
Abraham Tugalov

Oh! ดังนั้นจึงมีวิธี! โปรดช่วยฉันด้วยคำถามนี้
ยะซายา

ขอบคุณสำหรับคำตอบที่ยอดเยี่ยมนี้ ถ้าฉันต้องการทำGROUP BY DAY(created_date)อะไร ดูเหมือนว่าจะไม่ทำงานหากDAY()มีการเพิ่ม
เอสกิโม

41

ฉันใช้ Laravel 5.3, mysql 5.7.12, บน laravel homestead (0.5.0 ฉันเชื่อ)

แม้หลังจากการตั้งค่าการแก้ไขอย่างชัดเจน/etc/mysql/my.cnfเพื่อสะท้อน:

[mysqld]
sql_mode = STRICT_TRANS_TABLES,NO_ZERO_IN_DATE,NO_ZERO_DATE,ERROR_FOR_DIVISION_BY_ZERO,NO_AUTO_CREATE_USER,NO_ENGINE_SUBSTITUTION

ฉันยังคงได้รับข้อผิดพลาด

ฉันต้องเปลี่ยนconfig/database.phpจากtrueเป็นfalse:

    'mysql' => [
        'strict' => false, //behave like 5.6
        //'strict' => true //behave like 5.7
    ], 

อ่านเพิ่มเติม:

https://laracasts.com/discuss/channels/servers/set-set-sql-mode-on-homestead https://mattstauffer.co/blog/strict-mode-and-other-mysql-customizations-in-laravel -5-2


แดง! นั่นเป็นประโยชน์สำหรับผู้ใช้ Laravel +1 สำหรับสิ่งนั้น
Okafor T Kosiso

20

หากคุณกำลังใช้งาน wamp 3.0.6 หรือรุ่นสูงกว่าอื่น ๆ ที่มีความเสถียร 2.5 คุณอาจประสบปัญหานี้ประการแรกปัญหาอยู่ที่ sql คุณต้องตั้งชื่อฟิลด์ตาม แต่มีวิธีอื่นที่คุณสามารถแก้ไขได้ คลิกที่ไอคอนสีเขียวของ wamp mysql-> mysql settings-> sql_mode-> none หรือจากคอนโซลคุณสามารถเปลี่ยนค่าเริ่มต้น

mysql> set global sql_mode='STRICT_TRANS_TABLES,NO_ZERO_IN_DATE,NO_ZERO_DATE,ERROR_FOR_DIVISION_BY_ZERO,NO_AUTO_CREATE_USER,NO_ENGINE_SUBSTITUTION';
mysql> set session sql_mode='STRICT_TRANS_TABLES,NO_ZERO_IN_DATE,NO_ZERO_DATE,ERROR_FOR_DIVISION_BY_ZERO,NO_AUTO_CREATE_USER,NO_ENGINE_SUBSTITUTION';

มหัศจรรย์สร้างสิ่งที่เขาพูดแทรกคำสั่งshow variables like '%sql_mode%';ในบรรทัดคำสั่ง mysql การตั้งค่า sql_mode จะเปิดเผย
Jade Han

19

การเพิ่มบรรทัด (พูดถึงด้านล่าง) ในไฟล์: /etc/mysql/my.cnf

[mysqld]
sql_mode = STRICT_TRANS_TABLES,NO_ZERO_IN_DATE,NO_ZERO_DATE,ERROR_FOR_DIVISION_BY_ZERO,NO_AUTO_CREATE_USER,NO_ENGINE_SUBSTITUTION

ทำงานได้ดีสำหรับฉัน รุ่นเซิร์ฟเวอร์: 5.7.18-0ubuntu0.16.04.1 - (Ubuntu)


1
คุณใช้ RDS อยู่หรือเปล่า?
Mubasshir Pawle

@MubasshirPawle No
Jagdeep Singh

16

ไปที่ mysql หรือ phpmyadmin แล้วเลือกฐานข้อมูลจากนั้นก็เรียกใช้แบบสอบถามนี้และมันจะทำงาน มันใช้งานได้ดีสำหรับฉัน

SET GLOBAL sql_mode=(SELECT REPLACE(@@sql_mode,'ONLY_FULL_GROUP_BY',''));

เยี่ยมมาก .. ขอบคุณ :)
mohitesachin217

ความสุขของฉัน :) @mohit
Anil Gupta

ช่วยฉันทีหนึ่งครั้ง
JoeRaid

1
ยินดีต้อนรับ bro @TharinduEranga
Anil Gupta

1
แต่ปัญหากับการแก้ปัญหาคือทุกครั้งที่ฉันรีสตาร์ท mysql ฉันต้องเรียกใช้แบบสอบถามอีกครั้ง มันหมายถึงการแก้ปัญหาไม่ได้ถาวรหรือถาวร
Mushfiqur Rahman

10

สำหรับ mac:

1. คัดลอกค่าเริ่มต้น my-default.cnf เป็น /etc/my.cnf

sudo cp $(brew --prefix mysql)/support-files/my-default.cnf /etc/my.cnf

2.Change sql_mode ใน my.cnf โดยใช้โปรแกรมแก้ไขที่คุณชื่นชอบและตั้งค่านี้

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

3. รีสตาร์ทเซิร์ฟเวอร์ MySQL

mysql.server restart

ขอบคุณทำงานสำหรับฉันเช่นกัน แต่ฉันใช้ค่าเริ่มต้น mysql ของ Mac ดังนั้นฉันจึงไม่มีเส้นทางชง เพียงแค่ sudo cp my-default.cnf /etc/my.cnf
Mike Nguyen

2
@ ไมค์เหงียน sudo cp /usr/local/mysql-5.7.17-macos10.12-x86_64/support-files/my-default.cnf /etc/my.cnf sudo vi /etc/my.cnf ตั้ง sql_model sql_mode = STRICT_TAG , NO_ZERO_IN_DATE, NO_ZERO_DATE, ERROR_FOR_DIVISION_BY_ZERO, NO_AUTO_CREATE_USER, NO_ENGINE_SUBSTITUTION รีสตาร์ทเซิร์ฟเวอร์ MySQL
Yong Gao

7

นี่คือสิ่งที่ช่วยให้ฉันเข้าใจปัญหาทั้งหมด:

  1. https://stackoverflow.com/a/20074634/1066234
  2. https://dev.mysql.com/doc/refman/5.7/en/group-by-handling.html

และในตัวอย่างต่อไปนี้ของแบบสอบถามที่มีปัญหา

ปัญหา:

SELECT COUNT(*) as attempts, SUM(elapsed) as elapsedtotal, userid, timestamp, questionid, answerid, SUM(correct) as correct, elapsed, ipaddress FROM `gameplay`
                        WHERE timestamp >= DATE_SUB(NOW(), INTERVAL 1 DAY)
                        AND cookieid = #

แก้ไขได้โดยเพิ่มสิ่งนี้ลงในส่วนท้าย:

  GROUP BY timestamp, userid, cookieid, questionid, answerid, elapsed, ipaddress

หมายเหตุ: ดูข้อความแสดงข้อผิดพลาดใน PHP มันจะบอกคุณว่าปัญหาอยู่ที่ใด

ตัวอย่าง:

ข้อผิดพลาดในการสืบค้น MySQL 1140: ในแบบสอบถามแบบรวมที่ไม่มี GROUP BY นิพจน์ # 4 ของรายการ SELECT จะมีคอลัมน์ที่ไม่ได้รวบรวม 'db.gameplay.timestamp'; สิ่งนี้เข้ากันไม่ได้กับ sql_mode = only_full_group_by - การค้นหา: SELECT COUNT (*) เป็นความพยายาม SUM (ที่ผ่านไป) เป็นผ่านไปแล้ว, ผู้ใช้, การประทับเวลา, คำถาม, คำตอบ, SUM (ถูกต้อง) ที่ถูกต้อง (ตอนนี้ () ช่วงเวลา 1 วัน) และหมายเลขผู้ใช้ = 1

ในกรณีนี้นิพจน์ # 4หายไปใน GROUP BY


1
ขอบคุณสำหรับการชี้stackoverflow.com/questions/20074562/…
cwhsu

คำตอบที่ดีในการแก้ปัญหานี้ ขอบคุณมาก
Hansana Athukorala

7

สำหรับ localhost / wampserver 3 เราสามารถตั้งค่า sql-mode = user_mode เพื่อลบข้อผิดพลาดนี้:

click on wamp icon -> MySql -> MySql Setting -> sql-mode -> user_mode

จากนั้นรีสตาร์ท wamp หรือ apache


1
ฉันรู้ว่านี่อาจไม่ใช่การแก้ไขระยะยาวสำหรับปัญหานี้ แต่ตอนนี้ก็ช่วยได้อย่างแน่นอน บริษัท โฮสติ้งของฉันชื่อ Go Daddy กำลังใช้งาน MySQL V5.6.33 และ WampServer 3 ใช้งาน MySQL V5.7.14 ขอบคุณสำหรับโซลูชันการแก้ไขด่วนนี้
Alan N

4

คุณสามารถเพิ่มunique indexการgroup_id; หากคุณแน่ใจว่าgroup_idไม่เหมือนใคร

มันสามารถแก้ปัญหากรณีของคุณโดยไม่ต้องแก้ไขแบบสอบถาม

คำตอบที่ล่าช้า แต่ยังไม่ได้กล่าวถึงในคำตอบ บางทีมันควรจะตอบคำถามที่มีอยู่แล้วให้ครบ อย่างน้อยมันก็แก้ปัญหากรณีของฉันเมื่อฉันต้องแบ่งตารางที่มีเขตข้อมูลมากเกินไป


2

หากคุณมีข้อผิดพลาดกับSymfonyโดยใช้ตัวสร้างคิวรี Doctrineและหากเกิดข้อผิดพลาดนี้โดยorderBy :

ให้ความสนใจกับ selectคอลัมน์ที่คุณต้องการgroupByและใช้addGroupByแทนgroupBy:

$query = $this->createQueryBuilder('smth')->addGroupBy('smth.mycolumn');

ทำงานบนSymfony3 -


1

ขออภัยที่ไม่ใช้ SQL ที่แน่นอนของคุณ

ฉันใช้แบบสอบถามนี้เพื่อเอาชนะคำเตือน Mysql

SELECT count(*) AS cnt, `regions_id`
FROM regionables 
WHERE `regionable_id` = '115' OR `regionable_id` = '714'
GROUP BY `regions_id`
HAVING cnt > 1

จดบันทึกสิ่งที่สำคัญสำหรับฉัน

count(*) AS cnt
โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.