Computer >> บทช่วยสอนคอมพิวเตอร์ >  >> การเขียนโปรแกรม >> MySQL

หาค่าคอลัมน์ที่สอดคล้องกับ MAX() ของอีกคอลัมน์หนึ่งใน MySQL


สถานการณ์

ต้องการหา 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 บนข้อมูลเยอะ