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

MySQL ส่งหลาย ID เข้า Parameter เดียวด้วย FIND_IN_SET()

ใช้ FIND_IN_SET(str, csv_string) เพื่อตรวจสอบว่า String อยู่ใน Comma-Separated Values (CSV) String หรือไม่ เหมาะสำหรับส่งหลาย ID เข้า Parameter เดียวใน Application

ตัวอย่างการใช้งาน

1. สร้างตาราง

mysql> CREATE TABLE DemoTable1817 (
    EmployeeName VARCHAR(20),
    CountryName VARCHAR(20)
);
Query OK, 0 rows affected (0.00 sec)

2. เพิ่มข้อมูล

mysql> INSERT INTO DemoTable1817 VALUES('Chris', 'AUS');
mysql> INSERT INTO DemoTable1817 VALUES('David', 'UK');
mysql> INSERT INTO DemoTable1817 VALUES('Bob', 'US');

3. แสดงข้อมูล

mysql> SELECT * FROM DemoTable1817;
+--------------+-------------+
| EmployeeName | CountryName |
+--------------+-------------+
| Chris        | AUS         |
| David        | UK          |
| Bob          | US          |
+--------------+-------------+

4. Query: หาพนักงานที่ CountryName อยู่ใน 'US,UK'

mysql> SELECT * FROM DemoTable1817 WHERE FIND_IN_SET(CountryName, 'US,UK');

5. ผลลัพธ์

+--------------+-------------+
| EmployeeName | CountryName |
+--------------+-------------+
| David        | UK          |
| Bob          | US          |
+--------------+-------------+

การทำงานของ FIND_IN_SET

  • FIND_IN_SET('UK', 'US,UK') → คืน 2 (ตำแหน่งที่ 2, 1-based) → TRUE
  • FIND_IN_SET('AUS', 'US,UK') → คืน 0 (ไม่เจอ) → FALSE
  • คืนค่า 0 ถ้าไม่เจอหรือค่าเป็น NULL

การใช้งานใน Application (Parameter Binding)

// Java Example
String countries = "US,UK,AUS";  // มาจาก UI: Multi-select
String sql = "SELECT * FROM employees WHERE FIND_IN_SET(country, ?)";
PreparedStatement ps = con.prepareStatement(sql);
ps.setString(1, countries);
ResultSet rs = ps.executeQuery();

⚠️ ข้อจำกัดและข้อควรระวัง

ทางเลือกที่ดีกว่า (Best Practice)

-- 1. ใช้ IN () กับ Parameter หลายตัว (Dynamic SQL)
WHERE country IN (?, ?, ?)  -- ต้องสร้าง Placeholder ตามจำนวน

-- 2. ใช้ Temporary Table / Table-valued Parameter (MySQL 8.0+)
CREATE TEMPORARY TABLE tmp_countries (code VARCHAR(10));
INSERT INTO tmp_countries VALUES ('US'), ('UK');
SELECT * FROM employees e JOIN tmp_countries t ON e.country = t.code;

สรุป

FIND_IN_SET(col, 'val1,val2,val3') ใช้ส่งหลายค่าใน 1 Parameter ได้ง่าย เหมาะสำหรับ Prototype/ข้อมูลน้อย/Ad-hoc Query แต่ ไม่ใช้ Index ควรใช้ IN (...) หรือ Temporary Table สำหรับ Production/Big Data

ข้อจำกัดคำอธิบาย
ไม่ใช้ IndexFull Table Scan เสมอ (Function บน Column)
CSV String Lengthจำกัดด้วย max_allowed_packet / group_concat_max_len
Space Sensitivity'US, UK' ≠ 'US,UK' (มี Space ระหว่าง)
Data TypeArgument ทั้งคู่ต้องเป็น String