Sử dụng SUBSTRING_INDEX(str, ',', 1) để lấy phần tử đầu tiên (trước dấu phẩy đầu tiên).
Tạo bảng
mysql> CREATE TABLE DemoTable (CSV_Value VARCHAR(200));
Chèn danh sách CSV
mysql> INSERT INTO DemoTable VALUES('10,20,50,80');
mysql> INSERT INTO DemoTable VALUES('100,21,51,43');
mysql> INSERT INTO DemoTable VALUES('1,56,103,1090');
Xem dữ liệu
mysql> SELECT * FROM DemoTable;
+---------------+ | CSV_Value | +---------------+ | 10,20,50,80 | | 100,21,51,43 | | 1,56,103,1090 | +---------------+
Lấy phần tử đầu tiên
mysql> SELECT SUBSTRING_INDEX(CSV_Value, ',', 1) AS FIRST_ELEMENT FROM DemoTable;
+---------------+ | FIRST_ELEMENT | +---------------+ | 10 | | 100 | | 1 | +---------------+
Giải thích SUBSTRING_INDEX
SUBSTRING_INDEX(str, delim, count)count > 0: Trả về chuỗi từ đầu đến trước dấu phân cách thứcountcount = 1: Phần tử đầu tiên (trước dấu phẩy đầu)count < 0: Trả về chuỗi sau dấu phân cách thứ|count|từ cuối
Lấy phần tử thứ N
-- Phần tử thứ 2: SUBSTRING_INDEX(SUBSTRING_INDEX(str, ',', 2), ',', -1) -- Phần tử thứ 3: SUBSTRING_INDEX(SUBSTRING_INDEX(str, ',', 3), ',', -1) -- Phần tử cuối: SUBSTRING_INDEX(str, ',', -1)
Chuyển CSV thành hàng (MySQL 8.0+)
WITH RECURSIVE cte AS (
SELECT
TRIM(SUBSTRING_INDEX(CSV_Value, ',', 1)) AS val,
SUBSTRING(CSV_Value, LENGTH(SUBSTRING_INDEX(CSV_Value, ',', 1)) + 2) AS rest
FROM DemoTable
UNION ALL
SELECT
TRIM(SUBSTRING_INDEX(rest, ',', 1)),
SUBSTRING(rest, LENGTH(SUBSTRING_INDEX(rest, ',', 1)) + 2)
FROM cte WHERE rest != ''
)
SELECT val FROM cte;
Lưu ý thiết kế
Lưu CSV trong một cột vi phạm 1NF. Cân nhắc bảng con (1-nhiều) hoặc JSON (MySQL 5.7+) cho dữ liệu đa giá trị.