สร้างตารางและข้อมูลตัวอย่าง
mysql> create table DemoTable1996 ( ShippingDate datetime, CustomerName varchar(20) );
mysql> insert into DemoTable1996 values('2019-12-21 10:45:00','Chris');
mysql> insert into DemoTable1996 values('2019-12-21 12:10:00','David');
mysql> insert into DemoTable1996 values('2019-12-20 12:10:00','Bob');
ข้อมูลในตาราง
+---------------------+--------------+ | ShippingDate | CustomerName | +---------------------+--------------+ | 2019-12-21 10:45:00 | Chris | | 2019-12-21 12:10:00 | David | | 2019-12-20 12:10:00 | Bob | +---------------------+--------------+
Query ใช้ GROUP BY DATE(ShippingDate)
mysql> select * from DemoTable1996 group by date(ShippingDate);
ผลลัพธ์
+---------------------+--------------+ | ShippingDate | CustomerName | +---------------------+--------------+ | 2019-12-21 10:45:00 | Chris | | 2019-12-20 12:10:00 | Bob | +---------------------+--------------+
อธิบาย
GROUP BY DATE(ShippingDate)จับกลุ่มตามวันที่ (ตัดเวลาออก)- วันที่ 2019-12-21 มี 2 แถว (Chris, David) → เลือกแถวแรกที่เจอ (Chris)
- วันที่ 2019-12-20 มี 1 แถว (Bob) → เลือก Bob
⚠️ ข้อควรระวัง: Non-Aggregated Columns
Query นี้ใช้ SELECT * พร้อม GROUP BY บนคอลัมน์ที่ไม่ได้อยู่ใน GROUP BY และไม่ได้อยู่ใน Aggregate Function
- MySQL ก่อน 5.7.5: อนุญาต ให้ผลลัพธ์ไม่แน่นอน (Indeterminate)
- MySQL 5.7.5+ (Default
ONLY_FULL_GROUP_BY): Error หากไม่ได้อยู่ใน GROUP BY หรือ Aggregate - MySQL 8.0+: บังคับ
ONLY_FULL_GROUP_BYตลอด
วิธีเขียนที่ถูกต้องและปลอดภัย (Standard SQL)
-- 1. ใช้ Aggregate Function
SELECT DATE(ShippingDate) AS ShipDate, MIN(CustomerName) AS FirstCustomer
FROM DemoTable1996 GROUP BY DATE(ShippingDate);
-- 2. ใช้ ANY_VALUE() (MySQL 5.7.5+) ระบุว่า "รับค่าไหนก็ได้"
SELECT DATE(ShippingDate) AS ShipDate, ANY_VALUE(CustomerName) AS CustomerName
FROM DemoTable1996 GROUP BY DATE(ShippingDate);
-- 3. Subquery หา ID แล้ว JOIN กลับ
SELECT t1.* FROM DemoTable1996 t1
JOIN (
SELECT MIN(Id) AS Id FROM DemoTable1996 GROUP BY DATE(ShippingDate)
) t2 ON t1.Id = t2.Id;
สรุป
ตัวอย่างเดิมทำงานได้ใน MySQL เก่าหรือที่ปิด ONLY_FULL_GROUP_BY แต่ ไม่แนะนำ สำหรับ Production ควรเขียนแบบ Standard SQL ด้านบน