CodeGym /Các khóa học /SQL SELF /Trích xuất dữ liệu từ mảng: unnest(),

Trích xuất dữ liệu từ mảng: unnest(), array_length(), array_position()

SQL SELF
Mức độ , Bài học
Có sẵn

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

  1. 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ằng JOIN LATERAL hoặc CROSS JOIN, nhớ chú ý nhé.
  2. array_length() trả về NULL nếu mảng rỗng. Nếu mảng có thể rỗng, nhớ kiểm tra riêng vụ này.
  3. array_position() có thể trả về NULL nế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.

Bình luận
TO VIEW ALL COMMENTS OR TO MAKE A COMMENT,
GO TO FULL VERSION