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

Match ค่าอาเรย์ใน MySQL Query ด้วย IN() และ GROUP BY HAVING

หา Id ที่มี Value ครบทุกค่าใน Array ที่กำหนด

ใช้ WHERE Value IN (...) กรองแถวที่ Match แล้ว GROUP BY Id HAVING COUNT(*) = N โดย N = จำนวนค่าใน Array เพื่อให้แน่ใจว่าครบทุกค่า

สร้างตารางและข้อมูล

mysql> CREATE TABLE DemoTable1523 (Id INT, Value INT);
Query OK, 0 rows affected (0.76 sec)

mysql> INSERT INTO DemoTable1523 VALUES
    -> (1, 56), (2, 78), (1, 34), (2, 45), (1, 99);
Query OK, 5 rows affected

ข้อมูลทั้งหมด

+------+-------+
| Id   | Value |
+------+-------+
|    1 |    56 |
|    2 |    78 |
|    1 |    34 |
|    2 |    45 |
|    1 |    99 |
+------+-------+

คำสั่ง: หา Id ที่มี Value ครบ 34, 99, 56 (ทั้ง 3 ค่า)

mysql> SELECT Id FROM DemoTable1523
    -> WHERE Value IN ('34', '99', '56')
    -> GROUP BY Id
    -> HAVING COUNT(*) = 3;

ผลลัพธ์

+------+
| Id   |
+------+
|    1 |
+------+

คำอธิบาย

  • WHERE Value IN ('34','99','56') - กรองเหลือแถวที่ Value อยู่ในเซต (Id=1 มี 3 แถว, Id=2 มี 0 แถว)
  • GROUP BY Id - จัดกลุ่มตาม Id
  • HAVING COUNT(*) = 3 - ต้องมี 3 แถวในกลุ่ม (Match ทั้ง 3 ค่า)

⚠️ ข้อควรระวัง: ค่าซ้ำใน Array หรือใน Table

หาก Array มีค่าซ้ำ หรือ Table มี Duplicate (Id, Value) ให้ใช้ COUNT(DISTINCT Value)

HAVING COUNT(DISTINCT Value) = 3

วิธีอื่น: ใช้ JOIN กับ Derived Table / VALUES (MySQL 8.0+)

-- MySQL 8.0: VALUES ROW Constructor
SELECT t.Id
FROM DemoTable1523 t
JOIN (VALUES ROW(34), ROW(99), ROW(56)) AS v(val) ON t.Value = v.val
GROUP BY t.Id
HAVING COUNT(*) = 3;

กรณี Array มาจาก Application (Dynamic)

-- Java: สร้าง Placeholders
String placeholders = String.join(",", Collections.nCopies(values.size(), "?"));
String sql = "SELECT Id FROM DemoTable1523 WHERE Value IN (" + placeholders + ") GROUP BY Id HAVING COUNT(*) = ?";
PreparedStatement ps = conn.prepareStatement(sql);
for (int i = 0; i < values.size(); i++) ps.setInt(i+1, values.get(i));
ps.setInt(values.size()+1, values.size());