Hãy tưởng tượng bạn muốn cộng hai số, nhưng một trong các tham số lại được lưu dưới dạng chuỗi. Hoặc, ví dụ, bạn muốn lọc dữ liệu theo năm, nhưng ngày tháng lại lưu đầy đủ cả thời gian. PostgreSQL có thể sẽ không vui với ý tưởng này của bạn đâu, và bạn sẽ phải can thiệp để ép kiểu dữ liệu về đúng dạng cần thiết.
Chuyển đổi kiểu dữ liệu giúp bạn:
- Làm cho việc xử lý dữ liệu dễ dàng hơn để dùng trong tính toán.
- Tạo dữ liệu dễ đọc và có cấu trúc hơn để xuất ra hoặc phân tích.
- Loại bỏ lỗi liên quan đến việc không khớp kiểu dữ liệu.
Cơ bản về chuyển đổi kiểu dữ liệu: CAST() và ::
1. CAST() — ông anh cả của mọi chuyển đổi
Hàm CAST() là cách "chính thống" để chuyển giá trị từ kiểu dữ liệu này sang kiểu khác. Nó hoạt động như một phiên dịch viên đa năng.
Cú pháp:
CAST(giá_trị AS kiểu_dữ_liệu_đích)
Ví dụ 1: Chuyển chuỗi thành số.
SELECT CAST('123' AS INTEGER); -- Kết quả: 123
Ví dụ 2: Chuyển số thành chuỗi.
SELECT CAST(123 AS TEXT); -- Kết quả: '123'
Ví dụ 3: Chuyển ngày thành chuỗi.
SELECT CAST(NOW() AS TEXT); -- Kết quả: '2023-10-25 15:00:00.000000'
2. Toán tử :: — cách viết ngắn gọn hơn
Nếu bạn thấy CAST() hơi dài dòng, PostgreSQL có cú pháp ::. Đây là cách chuyển đổi ngắn gọn, được ưa chuộng vì sự tiện lợi.
Cú pháp:
giá_trị::kiểu_dữ_liệu_đích
Ví dụ 1: Chuyển chuỗi thành số.
SELECT '123'::INTEGER; -- Kết quả: 123
Ví dụ 2: Chuyển số thành chuỗi.
SELECT 123::TEXT; -- Kết quả: '123'
Ví dụ 3: Chuyển ngày thành chuỗi.
SELECT NOW()::TEXT; -- Kết quả: '2023-10-25 15:00:00.000000'
Ví dụ thực tế về chuyển đổi kiểu dữ liệu
1. Chuyển đổi số và chuỗi
Giả sử bạn có bảng students, trong đó cột student_id lưu dưới dạng chuỗi, nhưng bạn lại muốn so sánh nó với một giá trị số. Nếu không chuyển đổi thì chịu luôn.
| student_id | first_name | last_name | birth_date | grade |
|---|---|---|---|---|
| 101 | Alex | Lin | 2008-03-15 | 9 |
| 102 | Maria | Chi | 2009-07-22 | 8 |
| 103 | Axel | Ivy | 2007-11-30 | 10 |
| 104 | Nat | Sok | 2008-01-18 | 9 |
| 105 | Pol | Frez | 2009-05-05 | 8 |
Vì vậy trong truy vấn bạn cần ép cột student_id sang số:
SELECT *
FROM students
WHERE student_id::INTEGER = 101;
Truy vấn tương tự dùng CAST():
SELECT *
FROM students
WHERE CAST(student_id AS INTEGER) = 101;
Chuyển đổi ngày tháng
Khi cần lấy một phần của ngày hoặc chuyển nó thành chuỗi, chuyển đổi kiểu cũng rất hữu ích. Ví dụ, bạn có bảng courses với ngày bắt đầu khoá học trong cột start_date.
| course_id | course_name | start_date |
|---|---|---|
| 1 | Nhập môn Python | 2025-01-15 |
| 2 | Cơ bản SQL | 2025-03-01 |
| 3 | Phân tích dữ liệu | 2025-05-10 |
| 4 | Lập trình web | 2025-06-20 |
| 5 | Machine learning | 2025-09-05 |
Ví dụ: Lấy năm dưới dạng số.
SELECT start_date::DATE, start_date::TEXT, start_date::TIMESTAMP
FROM courses;
Kết quả sẽ như sau:
| start_date (DATE) | start_date (TEXT) | start_date (TIMESTAMP) |
|---|---|---|
| 2025-01-15 | 2025-01-15 | 2025-01-15 00:00:00 |
| 2025-03-01 | 2025-03-01 | 2025-03-01 00:00:00 |
| 2025-05-10 | 2025-05-10 | 2025-05-10 00:00:00 |
| 2025-06-20 | 2025-06-20 | 2025-06-20 00:00:00 |
| 2025-09-05 | 2025-09-05 | 2025-09-05 00:00:00 |
Ví dụ: Chuyển ngày thành "chuỗi thuần".
SELECT TO_CHAR(start_date, 'DD-MM-YYYY')
Kết quả sẽ như sau:
| to_char |
|---|
| 15-01-2025 |
| 01-03-2025 |
| 10-05-2025 |
| 20-06-2025 |
| 05-09-2025 |
Lỗi: Khi nào chuyển đổi bị fail?
Trick chuyển đổi dữ liệu không phải lúc nào cũng thành công. Đôi khi PostgreSQL sẽ báo luôn là nó "không hiểu" ý bạn. Đây là ví dụ kinh điển: bạn thử chuyển một chuỗi trông giống số, nhưng lại có ký tự thừa.
Ví dụ lỗi:
SELECT '123abc'::INTEGER;
-- LỖI: invalid input syntax for type integer: "123abc"
Để tránh mấy lỗi này, hãy chắc chắn dữ liệu thực sự có thể chuyển sang kiểu đích trước đã. Ví dụ, bạn có thể dùng regex hoặc kiểm tra thêm.
GO TO FULL VERSION