CodeGym /Các khóa học /SQL SELF /So sánh và chuyển đổi kiểu dữ liệu

So sánh và chuyển đổi kiểu dữ liệu

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

Tại sao phải quan tâm đến việc so sánh và chuyển đổi kiểu dữ liệu? Hãy tưởng tượng, trong bảng của bạn có một chuỗi "42", còn bạn lại muốn so sánh nó với số 42. Nhìn qua thì giống nhau nhỉ. Nhưng với database thì đây có thể là hai thứ hoàn toàn khác biệt. PostgreSQL sẽ không tự động đoán ý bạn đâu. Nếu không hiểu rõ cách nó so sánh các giá trị khác kiểu, bạn có thể nhận được kết quả kỳ lạ hoặc thậm chí là lỗi luôn.

Chuyển đổi cũng vậy thôi. Đôi khi bạn cần biến text thành số để đếm xem có bao nhiêu cái gì đó. Hoặc ngược lại — số cần được hiển thị đẹp mắt dưới dạng chuỗi. Hoặc lấy ngày tháng và xuất ra kiểu "01.01.2025" cho quen mắt người dùng.

Ví dụ khác: bạn lưu giá trị chính xác trong NUMERIC, nhưng để tính toán khoa học lại cần dùng FLOAT. Lúc này mà không chuyển đổi rõ ràng thì chịu luôn.

Tin vui là PostgreSQL xử lý chuyện này rất ổn. Nó cung cấp công cụ linh hoạt, dễ hiểu cho các tình huống này. Quan trọng là biết dùng và đừng ngại “soi” kỹ hơn một chút. Giờ mình cùng tìm hiểu nhé.

So sánh kiểu dữ liệu

PostgreSQL khá thông minh — nếu thấy bạn so sánh, ví dụ, INTEGERNUMERIC, nó sẽ tự động chuyển về cùng kiểu và so sánh luôn. Bình thường thôi, vì cả hai đều là số mà.

Nhưng nếu bạn thử so sánh chuỗi với giá trị boolean (TEXTBOOLEAN), database sẽ không hiểu bạn muốn gì đâu. Hai kiểu này bản chất khác nhau hoàn toàn, PostgreSQL sẽ trả về lỗi ngay. Tương tự, nếu bạn thử so sánh chuỗi "42" với số 42 mà không nói rõ là muốn chuyển chuỗi thành số.

Thực tế sẽ như này, ví dụ này sẽ báo lỗi:

SELECT '42' = 42; -- Lỗi! Chuỗi và số không so sánh được nếu không chuyển đổi

Còn như này thì chạy ngon lành:

SELECT '42'::INTEGER = 42; -- TRUE

Ở đây mình nói rõ: “Làm ơn, chuyển '42' thành số trước nhé”. Đó là lý do có cú pháp ::Kiểu mà mình đã nhắc tới. PostgreSQL thích khi bạn nói chuyện rõ ràng với nó.

So sánh kiểu số

Các kiểu số (INTEGER, NUMERIC, REAL) thường tương thích với nhau, nên bạn có thể so sánh mà không gặp khó khăn gì:

SELECT 42 = 42.0; -- TRUE
SELECT 42::REAL = 42.0; -- TRUE
SELECT 42.0::NUMERIC = 42; -- TRUE

Nhưng cẩn thận với số thực (REAL). Do giới hạn về độ chính xác, các số này đôi khi sẽ “lạ lắm”. Ví dụ:

SELECT 0.1 + 0.2 = 0.3; -- FALSE

Đây chắc là bí ẩn nổi tiếng nhất trong lập trình rồi nhỉ? So sánh này trả về FALSE vì cách lưu trữ số thực trong bộ nhớ máy tính.

So sánh kiểu text

Khi làm việc với kiểu text, bạn có thể so sánh CHAR, VARCHARTEXT, vì PostgreSQL sẽ tự động chuyển về kiểu tương thích:

SELECT 'Hello' = 'Hello'::TEXT; -- TRUE
SELECT 'World'::CHAR(5) = 'World'::VARCHAR; -- TRUE

Lưu ý về độ dài ký tự trong CHAR(n): nếu chuỗi ngắn hơn độ dài chỉ định, PostgreSQL sẽ tự động thêm dấu cách vào cuối.

Chuyển đổi kiểu dữ liệu

PostgreSQL có vài cách để chuyển đổi kiểu dữ liệu. Mình sẽ nói về hai cách chính:

Cách #1: Chuyển đổi rõ ràng (CAST)

Toán tử CAST cho phép bạn chỉ định rõ muốn chuyển kiểu nào sang kiểu nào. Ví dụ:

SELECT CAST('42' AS INTEGER); -- Chuyển chuỗi '42' thành số 42

Cách này đặc biệt tiện nếu bạn muốn code SQL dễ đọc hơn.

Cách #2: Viết tắt (::)

PostgreSQL còn có cú pháp ngắn gọn hơn để chuyển đổi kiểu — dùng ::. Vẫn là thao tác đó, chỉ là viết nhanh hơn:

SELECT '42'::INTEGER; -- Giống hệt CAST('42' AS INTEGER)

Chuyển đổi tự động

Nhiều trường hợp PostgreSQL sẽ tự động chuyển đổi dữ liệu. Ví dụ, dùng số trong trường kiểu chuỗi:

SELECT '42' = 42::TEXT; -- TRUE

Nhưng đừng quá tin vào chuyển đổi tự động, vì nó có thể gây bất ngờ cho dev khác. Đặc biệt với ngày tháng và chuỗi, nên chuyển đổi rõ ràng thì hơn.

Ví dụ chuyển đổi các kiểu dữ liệu khác nhau

Chuyển số thành text

Đôi khi bạn cần chuyển số thành text (ví dụ để tạo thông báo):

SELECT 42::TEXT; -- Chuyển số 42 thành chuỗi '42'
SELECT 3.14::TEXT; -- Chuyển số 3.14 thành chuỗi '3.14'

Chuyển text thành số

Nếu chuỗi chứa số hợp lệ, bạn có thể chuyển nó thành kiểu số:

SELECT '123'::INTEGER; -- Chuyển chuỗi '123' thành số 123
SELECT '3.14'::FLOAT;  -- Chuyển chuỗi '3.14' thành số 3.14

Nhưng nếu text không chuyển được thì sao? Ví dụ:

SELECT 'Hello'::INTEGER; -- Lỗi: không thể chuyển 'Hello' thành số

Để tránh lỗi kiểu này, bạn có thể dùng hàm TRY_CAST() (từ PostgreSQL 14 trở lên) hoặc kiểm tra dữ liệu trước.

Chuyển ngày thành text và ngược lại

Khi chuyển đổi ngày tháng, bạn có thể dùng hàm TO_CHAR()TO_DATE():

SELECT TO_CHAR(CURRENT_DATE, 'YYYY-MM-DD'); -- Chuyển ngày thành chuỗi
SELECT TO_DATE('2023-10-25', 'YYYY-MM-DD'); -- Chuyển chuỗi thành ngày

Chuyển đổi giữa BOOLEAN và text

Kiểu dữ liệu logic BOOLEAN cũng có thể chuyển thành chuỗi:

SELECT TRUE::TEXT; -- 'true'
SELECT FALSE::TEXT; -- 'false'

Hoặc ngược lại:

SELECT 'true'::BOOLEAN; -- TRUE
SELECT 'false'::BOOLEAN; -- FALSE

Lưu ý, các chuỗi như 'yes' hoặc 'no' sẽ không tự động chuyển đổi được đâu nhé.

Thực hành: tất cả bằng ví dụ thực tế

Tạo bảng minh họa việc dùng các kiểu dữ liệu khác nhau:

id number_as_text - TEXT number_as_integer - INTEGER date_as_text - TEXT actual_date - DATE
1 42 42 2023-10-25 2023-10-25
2 3.14 NULL 2023-10-24 NULL
3 Hello 123 NULL NULL

Giờ thử các thao tác chuyển đổi nhé:

-- Chuyển text thành số
SELECT number_as_text::INTEGER FROM data_types_demo WHERE number_as_text = '42';

-- Chuyển ngày thành text
SELECT TO_CHAR(actual_date, 'DD/MM/YYYY') FROM data_types_demo;

-- Chuyển chuỗi thành ngày
SELECT TO_DATE(date_as_text, 'YYYY-MM-DD') FROM data_types_demo;

Lỗi thường gặp khi chuyển đổi dữ liệu

Lỗi phổ biến gồm có:

  1. Thử chuyển đổi dữ liệu không đúng định dạng mong đợi (ví dụ, chuỗi 'Hello' sang INTEGER).
  2. Vấn đề làm tròn và độ chính xác khi làm việc với số thực.
  3. Dùng sai định dạng khi chuyển đổi ngày tháng.

Để tránh lỗi, nên:

  • Luôn kiểm tra dữ liệu trước khi chuyển đổi.
  • Dùng hàm xử lý lỗi (TRY_CAST hoặc CASE).
  • Chỉ định định dạng rõ ràng khi chuyển đổi ngày tháng.
-- Kiểm tra dữ liệu trước khi chuyển đổi
SELECT 
    CASE 
        WHEN number_as_text ~ '^\d+$' THEN number_as_text::INTEGER
        ELSE NULL
    END AS safe_integer
FROM data_types_demo;

Dùng cách này để bảo vệ truy vấn của bạn khỏi những tình huống bất ngờ nhé!

Đến đây bạn đã có kỹ năng cơ bản để so sánh và chuyển đổi kiểu dữ liệu trong PostgreSQL rồi. Còn lại chỉ là luyện tập, luyện tập và luyện tập thôi. Hẹn gặp lại ở các bài giảng tiếp theo nhé!

2
Nhiệm vụ
SQL SELF, mức độ, bài học
Đã khóa
Chuyển đổi giá trị chuỗi thành số
Chuyển đổi giá trị chuỗi thành số
2
Nhiệm vụ
SQL SELF, mức độ, bài học
Đã khóa
Chuyển đổi ngày tháng
Chuyển đổi ngày tháng
Bình luận
TO VIEW ALL COMMENTS OR TO MAKE A COMMENT,
GO TO FULL VERSION