เพื่อหลีกเลี่ยงผลลัพธ์ที่ไม่คาดคิดเมื่อใช้GROUP BY
โดยไม่มีฟังก์ชันการรวมตามที่ใช้ในคำตอบที่ยอมรับเนื่องจาก MySQL มีอิสระในการดึงค่าใด ๆภายในชุดข้อมูลที่ถูกจัดกลุ่มเมื่อไม่ได้ใช้ฟังก์ชันรวม[sic]และปัญหาเกี่ยวกับONLY_FULL_GROUP_BY
และปัญหาเกี่ยวกับโปรดลองใช้การยกเว้นการเข้าร่วม
การรวมเข้าร่วม - เอนทิตีที่ชัดเจน
สมมติว่าชื่อและนามสกุลเป็นดัชนีที่ไม่ซ้ำกัน(ไม่คลุมเครือ)อีกทางเลือกหนึ่งGROUP BY
คือการจัดเรียงโดยใช้LEFT JOIN
เพื่อกรองชุดผลลัพธ์หรือที่เรียกว่าการยกเว้น JOIN
ดูการสาธิต
เรียงลำดับขึ้น(AZ)
หากต้องการดึงชื่อที่แตกต่างกันซึ่งเรียงลำดับตามนามสกุลจาก AZ
สอบถาม
SELECT t1.*
FROM table_name AS t1
LEFT JOIN table_name AS t2
ON t1.firstname = t2.firstname
AND t1.lastname > t2.lastname
WHERE t2.id IS NULL;
ผลลัพธ์
| id | firstname | lastname |
|----|-----------|----------|
| 2 | Bugs | Bunny |
| 1 | John | Doe |
ลำดับมากไปน้อย(ZA)
หากต้องการดึงข้อมูลชื่อที่แตกต่างซึ่งได้รับคำสั่งจากนามสกุลจาก ZA
สอบถาม
SELECT t1.*
FROM table_name AS t1
LEFT JOIN table_name AS t2
ON t1.firstname = t2.firstname
AND t1.lastname < t2.lastname
WHERE t2.id IS NULL;
ผลลัพธ์
| id | firstname | lastname |
|----|-----------|----------|
| 2 | Bugs | Bunny |
| 3 | John | Johnson |
จากนั้นคุณสามารถสั่งซื้อข้อมูลผลลัพธ์ตามต้องการ
การรวมเข้าร่วม - เอนทิตีที่ไม่ชัดเจน
หากการรวมกันของชื่อและนามสกุลไม่ซ้ำกัน(คลุมเครือ)และคุณมีค่าหลายแถวที่เหมือนกันคุณสามารถกรองชุดผลลัพธ์โดยรวมเงื่อนไข OR ในเกณฑ์ JOIN เพื่อกรองตามรหัสด้วย
ดูการสาธิต
ข้อมูล table_name
(1, 'John', 'Doe'),
(2, 'Bugs', 'Bunny'),
(3, 'John', 'Johnson'),
(4, 'John', 'Doe'),
(5, 'John', 'Johnson')
สอบถาม
SELECT t1.*
FROM table_name AS t1
LEFT JOIN table_name AS t2
ON t1.firstname = t2.firstname
AND (t1.lastname > t2.lastname
OR (t1.firstname = t1.firstname AND t1.lastname = t2.lastname AND t1.id > t2.id))
WHERE t2.id IS NULL;
ผลลัพธ์
| id | firstname | lastname |
|----|-----------|----------|
| 1 | John | Doe |
| 2 | Bugs | Bunny |
แบบสอบถามย่อยที่สั่ง
แก้ไข
คำตอบเดิมของฉันโดยใช้แบบสอบถามย่อยที่สั่งซื้อถูกเขียนก่อนMySQL 5.7.5ซึ่งไม่สามารถใช้งานได้อีกต่อไปเนื่องจากการเปลี่ยนแปลงด้วยONLY_FULL_GROUP_BY
ซึ่งใช้ไม่ได้แล้วเนื่องจากมีการเปลี่ยนแปลงด้วยโปรดใช้ตัวอย่างการเข้าร่วมการยกเว้นด้านบนแทน
นอกจากนี้ยังเป็นสิ่งสำคัญที่จะต้องทราบ; เมื่อONLY_FULL_GROUP_BY
ปิดการใช้งาน(พฤติกรรมดั้งเดิมก่อน MySQL 5.7.5)การใช้งานGROUP BY
โดยไม่รวมฟังก์ชั่นอาจให้ผลลัพธ์ที่ไม่คาดคิดเพราะ MySQL มีอิสระที่จะเลือกค่าใด ๆภายในชุดข้อมูลที่ถูกจัดกลุ่ม[sic] [sic]
ความหมายID
หรือlastname
ค่าอาจถูกดึงที่ไม่เกี่ยวข้องกับfirstname
แถวที่ดึงออกมา
คำเตือน
ด้วย MySQL GROUP BY
อาจไม่ให้ผลลัพธ์ที่คาดหวังเมื่อใช้กับORDER BY
ดูตัวอย่างกรณีทดสอบ
วิธีที่ดีที่สุดของการนำไปใช้เพื่อให้มั่นใจถึงผลลัพธ์ที่คาดหวังคือการกรองขอบเขตชุดผลลัพธ์โดยใช้แบบสอบถามย่อยที่สั่งซื้อ
ข้อมูล table_name
(1, 'John', 'Doe'),
(2, 'Bugs', 'Bunny'),
(3, 'John', 'Johnson')
สอบถาม
SELECT * FROM (
SELECT * FROM table_name ORDER BY ID DESC
) AS t1
GROUP BY FirstName
ผลลัพธ์
| ID | first | last |
|----|-------|---------|
| 2 | Bugs | Bunny |
| 3 | John | Johnson |
การเปรียบเทียบ
เพื่อแสดงผลลัพธ์ที่ไม่คาดคิดเมื่อใช้GROUP BY
ร่วมกับORDER BY
สอบถาม
SELECT * FROM table_name GROUP BY FirstName ORDER BY ID DESC
ผลลัพธ์
| ID | first | last |
|----|-------|-------|
| 2 | Bugs | Bunny |
| 1 | John | Doe |