สถานการณ์
ต้องการหา ProductId ที่มี ProductAmount สูงสุด (MAX) ไม่ใช่แค่ค่า MAX เท่านั้น
วิธีแก้: ใช้ Subquery
Subquery หา MAX Value ก่อน แล้วค่อย Filter ตารางหลัก
ตัวอย่างการใช้งาน
1. สร้างตาราง
mysql> CREATE TABLE DemoTable (
-> ProductId INT,
-> ProductAmount INT
-> );
Query OK, 0 rows affected (0.78 sec)
2. เพิ่มข้อมูล
mysql> INSERT INTO DemoTable VALUES(1001, 7895); Query OK, 1 row affected (0.32 sec) mysql> INSERT INTO DemoTable VALUES(1003, 8903); Query OK, 1 row affected (0.13 sec) mysql> INSERT INTO DemoTable VALUES(1010, 7690); Query OK, 1 row affected (0.15 sec) mysql> INSERT INTO DemoTable VALUES(2010, 8450); Query OK, 1 row affected (0.12 sec)
3. แสดงข้อมูลทั้งหมด
mysql> SELECT * FROM DemoTable;
ผลลัพธ์:
+-----------+---------------+ | ProductId | ProductAmount | +-----------+---------------+ | 1001 | 7895 | | 1003 | 8903 | | 1010 | 7690 | | 2010 | 8450 | +-----------+---------------+ 4 rows in set (0.00 sec)
4. หา ProductId ที่มี ProductAmount สูงสุด
mysql> SELECT * FROM DemoTable
-> WHERE ProductAmount = (SELECT MAX(ProductAmount) FROM DemoTable);
ผลลัพธ์:
+-----------+---------------+ | ProductId | ProductAmount | +-----------+---------------+ | 1003 | 8903 | +-----------+---------------+ 1 row in set (0.05 sec)
วิธีอื่นๆ
1. ใช้ ORDER BY + LIMIT (ง่ายกว่า)
SELECT * FROM DemoTable ORDER BY ProductAmount DESC LIMIT 1;
2. ใช้ JOIN (สำหรับหลายคอลัมน์/หลายตาราง)
SELECT d.* FROM DemoTable d JOIN (SELECT MAX(ProductAmount) AS MaxAmount FROM DemoTable) m ON d.ProductAmount = m.MaxAmount;
3. ใช้ Window Function (MySQL 8.0+)
SELECT * FROM (
SELECT *, ROW_NUMBER() OVER (ORDER BY ProductAmount DESC) AS rn
FROM DemoTable
) t WHERE rn = 1;
กรณีมีหลายแถวเท่ากันสูงสุด (Tie)
WHERE ... = (SELECT MAX...)→ คืนทุกแถวที่เท่าสูงสุดORDER BY ... LIMIT 1→ คืนแค่ 1 แถว (ไม่ deterministic)- ใช้
ROW_NUMBER()หรือRANK()ควบคุม Tie-breaking
กรณีการใช้งานจริง
- หาสินค้าขายดีที่สุด (Top selling product)
- หาพนักงานมียอดขายสูงสุด
- หาลูกค้าสั่งซื้อมากที่สุด
- หาวันที่มียอดขายสูงสุด
Performance Tips
- สร้าง Index บน ProductAmount:
CREATE INDEX idx_amount ON DemoTable(ProductAmount) - Subquery แบบ Correlated ช้ากว่า Non-correlated
- MySQL 8.0+ Window Function เร็วกว่า Subquery บนข้อมูลเยอะ