Làm việc với mảng không chỉ dừng lại ở việc tạo và lưu trữ — nhiều lúc tụi mình cần lấy từng phần tử ra hoặc phân tích nội dung bên trong. PostgreSQL có sẵn mấy hàm built-in để xử lý vụ này. Cùng xem từng cái nhé.
Hàm unnest(): bung mảng thành từng dòng
Hàm unnest() kiểu như "giải nén" mảng, biến từng phần tử thành một dòng riêng biệt. Cực kỳ tiện nếu bạn muốn thao tác với dữ liệu mảng dưới dạng bảng.
Ví dụ 1: Bung mảng đơn giản
Giả sử tụi mình có một mảng tên các khoa:
SELECT ARRAY['Tin học', 'Toán học', 'Vật lý'] AS khoa;
Bây giờ muốn lấy từng phần tử thành dòng riêng. Dùng unnest() nhé:
SELECT unnest(ARRAY['Tin học', 'Toán học', 'Vật lý']) AS khoa;
Kết quả:
| khoa |
|---|
| Tin học |
| Toán học |
| Vật lý |
Ví dụ 2: Bung mảng trong bảng
Giả sử có bảng courses:
CREATE TABLE courses (
course_id SERIAL PRIMARY KEY,
course_name TEXT,
tags TEXT[]
);
INSERT INTO courses (course_name, tags)
VALUES
('Thuật toán', ARRAY['Lập trình', 'Tin học']),
('Đại số tuyến tính', ARRAY['Toán học', 'Đại số']),
('Cơ sở vật lý', ARRAY['Vật lý', 'Chung']);
Bây giờ lấy hết các tag trong mảng ra:
SELECT course_name, unnest(tags) AS tag
FROM courses;
Kết quả:
| course_name | tag |
|---|---|
| Thuật toán | Lập trình |
| Thuật toán | Tin học |
| Đại số tuyến tính | Toán học |
| Đại số tuyến tính | Đại số |
| Cơ sở vật lý | Vật lý |
| Cơ sở vật lý | Chung |
Nhìn thấy không, mỗi phần tử trong mảng thành một dòng riêng trong bảng luôn.
Hàm array_length(): xác định kích thước mảng
Một hàm quan trọng nữa là array_length(). Nó trả về độ dài của mảng (tức là số phần tử) cho chiều chỉ định.
Ví dụ 1: Đếm phần tử trong mảng một chiều
Lấy mảng này nhé:
SELECT ARRAY['Táo', 'Chuối', 'Cam'] AS trái_cây;
Muốn biết có bao nhiêu trái cây trong mảng:
SELECT array_length(ARRAY['Táo', 'Chuối', 'Cam'], 1) AS độ_dài;
Kết quả:
| độ_dài |
|---|
| 3 |
Ở đây 1 là chỉ chiều của mảng. Trong PostgreSQL, mảng có thể nhiều chiều (kiểu như mảng 2 chiều), nhưng vụ đó để dịp khác nói sau.
Ví dụ 2: Đếm phần tử trong mảng của bảng
Xem mỗi khoá học có bao nhiêu tag:
SELECT course_name, array_length(tags, 1) AS so_luong_tag
FROM courses;
Kết quả:
| course_name | so_luong_tag |
|---|---|
| Thuật toán | 2 |
| Đại số tuyến tính | 2 |
| Cơ sở vật lý | 2 |
Hàm này kiểu như bảo: “Ê, ở đây có hai phần tử nha!”, vậy là dễ phân tích dữ liệu hơn nhiều.
Hàm array_position(): tìm giá trị trong mảng
Giờ tưởng tượng bạn cần tìm một phần tử cụ thể trong mảng. Hàm array_position() sẽ giúp: nó trả về vị trí xuất hiện đầu tiên của phần tử đó.
Ví dụ 1: Tìm phần tử
Giả sử có mảng này:
SELECT ARRAY['Đỏ', 'Xanh', 'Lục', 'Vàng'] AS màu_sắc;
Thử tìm vị trí của phần tử "Xanh":
SELECT array_position(ARRAY['Đỏ', 'Xanh', 'Lục', 'Vàng'], 'Xanh') AS vị_trí;
Kết quả:
| vị_trí |
|---|
| 2 |
Nếu phần tử không có, hàm trả về NULL. Thử kiểm tra nhé:
SELECT array_position(ARRAY['Đỏ', 'Xanh', 'Lục', 'Vàng'], 'Đen') AS vị_trí;
Kết quả:
| vị_trí |
|---|
| NULL |
Ví dụ 2: Tìm trong mảng của bảng
Bạn muốn biết khoá học nào có tag "Tin học". Đầu tiên tìm các dòng cần thiết:
SELECT course_name, array_position(tags, 'Tin học') AS vị_trí
FROM courses;
Kết quả:
| course_name | vị_trí |
|---|---|
| Thuật toán | 2 |
| Đại số tuyến tính | NULL |
| Cơ sở vật lý | NULL |
Giờ thêm điều kiện lọc, chỉ lấy dòng có tag thôi:
SELECT course_name
FROM courses
WHERE array_position(tags, 'Tin học') IS NOT NULL;
Kết quả:
| course_name |
|---|
| Thuật toán |
Hàm array_position() giúp tìm dữ liệu trong mảng cực nhanh, nên nó là một trong những hàm quan trọng nhất khi làm việc với mảng trong PostgreSQL.
Ứng dụng thực tế của các hàm này
unnest()— dùng để chuyển mảng thành dòng. Cực kỳ hữu ích khi phân tích dữ liệu, làm báo cáo hoặc xử lý tag.array_length()— quá hợp để kiểm tra độ dài mảng. Ví dụ, dùng để validate dữ liệu: kiểm tra mảng có rỗng không.array_position()— công cụ xịn để tìm phần tử, dù là danh mục sản phẩm, sinh viên tham gia dự án hay từ khoá trong mô tả.
Lỗi thường gặp khi dùng các hàm này
unnest()có thể làm tăng gấp đôi số dòng nếu dùng với nhiều cột mảng cùng lúc. Giải quyết bằngJOIN LATERALhoặcCROSS JOIN, nhớ chú ý nhé.array_length()trả vềNULLnếu mảng rỗng. Nếu mảng có thể rỗng, nhớ kiểm tra riêng vụ này.array_position()có thể trả vềNULLnếu không tìm thấy phần tử. Nên lúc lọc nhớ để ý trường hợp này (IS NOT NULL).
Ví dụ thực tế ngoài đời
Mảng trong PostgreSQL không chỉ là lý thuyết đâu, mà còn cực kỳ hữu ích trong dự án thực tế. Ví dụ, bạn làm blog, mỗi bài viết có danh sách tag — lưu tag bằng mảng giúp lọc bài theo chủ đề hoặc làm top danh mục hot rất dễ.
Hoặc bạn phân tích hành vi người dùng, mỗi người chọn nhiều khoá học hoặc sản phẩm. Tất cả sở thích đó lưu vào mảng — xử lý cũng tiện luôn.
Thêm nữa, mảng giúp validate dữ liệu: dùng array_length() để giới hạn số phần tử — ví dụ, không cho người dùng chọn quá năm mục chẳng hạn.
GO TO FULL VERSION