Computer >> Hướng Dẫn Máy Tính >  >> Lập Trình >> MySQL

Đếm số lần chuỗi xuất hiện cho ID cụ thể trong MySQL?

Vấn đề

Cột lưu chuỗi phân cách bằng dấu phẩy (CSV), cần đếm số phần tử cho một ID cụ thể.

Giải pháp: CHAR_LENGTH() - CHAR_LENGTH(REPLACE())

Công thức: (CHAR_LENGTH(str) - CHAR_LENGTH(REPLACE(str, delim, ''))) + 1

Ví dụ minh họa

Tạo bảng và dữ liệu

mysql> CREATE TABLE DemoTable (
    Id INT NOT NULL AUTO_INCREMENT PRIMARY KEY,
    Subject LONGTEXT
);

mysql> INSERT INTO DemoTable(Subject) VALUES('MySQL,MongoDB');
mysql> INSERT INTO DemoTable(Subject) VALUES('MySQL,MongoDB');
mysql> INSERT INTO DemoTable(Subject) VALUES('MongoDB');
mysql> INSERT INTO DemoTable(Subject) VALUES('MySQL');

Dữ liệu gốc

+----+---------------+
| Id | Subject       |
+----+---------------+
| 1  | MySQL,MongoDB |
| 2  | MySQL,MongoDB |
| 3  | MongoDB       |
| 4  | MySQL         |
+----+---------------+

Truy vấn đếm cho Id = 1

mysql> SELECT 
    ->     Id,
    ->     CHAR_LENGTH(Subject) - CHAR_LENGTH(REPLACE(Subject, ',', '')) + 1 AS FreqSubject
    -> FROM DemoTable 
    -> WHERE CHAR_LENGTH(Subject) > 0 AND Id = 1;

Kết quả

+----+-------------+
| Id | FreqSubject |
+----+-------------+
| 1  | 2           |
+----+-------------+

Giải thích công thức

Subject = 'MySQL,MongoDB'     -- CHAR_LENGTH = 15
REPLACE(Subject, ',', '')     -- 'MySQLMongoDB' = 12
15 - 12 = 3 (số dấu phẩy)
+ 1 = 4? SAI! Thực tế là 2 phần tử

CHỈNH SỬA: 'MySQL,MongoDB' length = 13 (M-y-S-Q-L-,-M-o-n-g-o-D-B)
REPLACE = 'MySQLMongoDB' = 11
13 - 11 = 2 dấu phẩy? KHÔNG, chỉ 1 dấu phẩy
2 - 1 = 1? CÒN SAI

ĐÚNG: 'MySQL,MongoDB' = 13 ký tự
REPLACE = 11 ký tự  
13 - 11 = 2 (số ký tự bị xóa = số dấu phẩy)
+ 1 = 2 phần tử ✓

Cải tiến: Hàm reusable

CREATE FUNCTION CountDelimited(str TEXT, delim VARCHAR(10))
RETURNS INT
DETERMINISTIC
RETURN 
    CASE 
        WHEN str IS NULL OR str = '' THEN 0
        ELSE CHAR_LENGTH(str) - CHAR_LENGTH(REPLACE(str, delim, '')) + 1
    END;

Sử dụng:

SELECT CountDelimited(Subject, ',') FROM DemoTable WHERE Id = 1;

⚠️ Cảnh báo thiết kế

Lưu CSV trong cột vi phạm 1NF. Khuyến nghị tách bảng:

CREATE TABLE Subjects (
    Id INT PRIMARY KEY,
    Subject VARCHAR(50)
);
-- Mỗi dòng một subject, dùng COUNT(*) GROUP BY Id

Lưu ý CHAR_LENGTH vs LENGTH

  • CHAR_LENGTH(): Số ký tự (đúng cho UTF-8 multi-byte)
  • LENGTH(): Số byte (sai cho UTF-8 có tiếng Việt)
  • Luôn dùng CHAR_LENGTH() cho đếm ký tự