CodeGym /Các khóa học /SQL SELF /Tìm kiếm dữ liệu trong mảng: ANY, AL...

Tìm kiếm dữ liệu trong mảng: ANY, ALL, array_contains()

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

Mảng thường được dùng để lưu nhiều giá trị trong một cột — ví dụ như tag, số điện thoại, vai trò hoặc sở thích. Nhưng làm sao để biết trong mảng có giá trị mình cần không, hoặc ngược lại — tất cả phần tử có thỏa mãn điều kiện nào đó không? PostgreSQL cung cấp mấy công cụ tiện cho việc này: ANY, ALLarray_contains(). Cùng xem từng cái một nhé.

ANY là gì?

Giả sử bạn có một mảng chứa nhiều giá trị, ví dụ ID sản phẩm, số điện thoại hoặc danh sách sở thích. Thường sẽ có lúc bạn cần kiểm tra xem trong mảng có giá trị cụ thể nào đó không. Lúc này, toán tử ANY sẽ phát huy tác dụng. Nó giúp kiểm tra xem "đối tượng cần tìm" của mình có nằm trong mảng không.

Cú pháp ANY

SELECT *
FROM your_table
WHERE value = ANY(array_column);

Ở đây:

  • array_column — là mảng mà mình kiểm tra.
  • value — là giá trị mình muốn tìm trong mảng.

Ví dụ dùng ANY

Giả sử có bảng students với cấu trúc như sau:

id name hobbies
1 Otto {doc sach, boi loi, co vua}
2 Eva {am nhac, doc sach, the thao}
3 Alex {ve, am nhac}
4 Maria {co vua, bong da}

Bạn muốn tìm sinh viên nào có sở thích là bơi lội. Truy vấn sẽ như sau:

SELECT *
FROM students
WHERE 'boi loi' = ANY(hobbies);

Kết quả:

id name hobbies
1 Otto {doc sach, boi loi, co vua}

Nói ngắn gọn, ANY kiểm tra: "Trong mảng này có giá trị này không?".

Tin nhưng phải kiểm hết! Dùng ALL

Bây giờ tưởng tượng ngược lại: bạn cần chắc chắn tất cả phần tử trong mảng đều thỏa mãn một quy tắc nào đó. PostgreSQL có toán tử ALL cho việc này. Nó giúp kiểm tra xem tất cả phần tử trong mảng có thỏa mãn điều kiện, ví dụ như lớn hơn một số nào đó, hoặc bằng một giá trị nào đó, hoặc bất kỳ điều kiện logic nào khác.

Cú pháp ALL

SELECT *
FROM your_table
WHERE value < ALL(array_column);

Ở đây:

  • array_column — là mảng mình kiểm tra.
  • value < ALL(...) nghĩa là tất cả phần tử trong mảng phải lớn hơn giá trị này.

Quay lại bảng students. Giả sử bạn muốn tìm sinh viên mà tất cả sở thích đều bắt đầu bằng chữ "doc sach". Truy vấn:

SELECT *
FROM students
WHERE 'doc sach' = ALL(hobbies);

Kết quả sẽ rỗng, vì không ai có tất cả sở thích đều là "doc sach". Để ví dụ dễ hiểu hơn (và chạy được), thử nghĩ về dữ liệu số nhé.

Giả sử có bảng orders:

id customer prices
1 Otto {100, 200, 300}
2 Eva {50, 60, 70}
3 Alex {500, 600, 700}

Tìm tất cả đơn hàng mà mỗi giá đều nhỏ hơn 400:

SELECT *
FROM orders
WHERE 400 > ALL(prices);

Kết quả:

id customer prices
1 Otto {100, 200, 300}
2 Eva {50, 60, 70}

Lọc dòng theo nội dung mảng

Mình đã xem qua các hàm và toán tử cơ bản để tìm kiếm dữ liệu trong mảng, nhưng thực tế dùng như nào? Xem vài ví dụ nhé.

Ví dụ 1: Tìm sinh viên có ít nhất một sở thích là âm nhạc

Bảng gốc:

id name hobbies
1 Otto {doc sach, am nhac, chay}
2 Eva {ve, boi loi}
3 Maria {am nhac, boxing}
4 Alex {bong da, boxing, choi ban}
SELECT *
FROM students
WHERE 'am nhac' = ANY(hobbies);

Kết quả:

id name hobbies
1 Otto {doc sach, am nhac, chay}
3 Maria {am nhac, boxing}

Ví dụ 2: Tìm đơn hàng mà tất cả giá đều lớn hơn 100

Bảng orders gốc:

id customer prices
1 Otto {150, 200, 300}
2 Eva {50, 120, 130}
3 Maria {200, 250, 100}
4 Alex {110, 115, 120}
SELECT *
FROM orders
WHERE 100 < ALL(prices);

Kết quả:

id customer prices
1 Otto {150, 200, 300}
4 Alex {110, 115, 120}

Lỗi thường gặp và cách tránh

Khi làm việc với mảng, nhất là khi tìm kiếm dữ liệu, có vài "bẫy" dễ dính lắm nha.

Lỗi: Dùng sai ANY hoặc ALL. Ví dụ, nếu bạn nhầm lẫn giữa các toán tử, kết quả sẽ rất bất ngờ.

-- Sai:
SELECT *
FROM students
WHERE hobbies = ANY('doc sach');

Ở ví dụ này, lỗi là hobbies là mảng, còn 'doc sach' là chuỗi. Chính mảng mới nên kiểm tra với ANY, không phải ngược lại.

Lỗi: Chỉ số mảng bắt đầu từ 1 chứ không phải 0. Nếu bạn dùng mảng trong các hàm khác hoặc lấy phần tử thủ công, nhớ đặc điểm này của PostgreSQL nhé.

Lỗi: Không tạo index cho mảng. Nếu bạn thường xuyên tìm kiếm trên mảng (ANY, ALL), tạo index sẽ giúp truy vấn nhanh hơn nhiều.

2
Nhiệm vụ
SQL SELF, mức độ, bài học
Đã khóa
Sử dụng `ANY` để tìm kiếm trong mảng
Sử dụng `ANY` để tìm kiếm trong mảng
1
Khảo sát/đố vui
, cấp độ , bài học
Không có sẵn
Mảng và cách làm việc với chúng
Mảng và cách làm việc với chúng
Bình luận
TO VIEW ALL COMMENTS OR TO MAKE A COMMENT,
GO TO FULL VERSION