Sắp xếp và định dạng — nghe thì hợp lý và hữu ích thật. Nhưng đôi khi dễ bị rối và kết quả lại không như mong đợi. Cùng nhau xem qua những lỗi phổ biến nhất để dữ liệu của bạn luôn đẹp và đúng thứ tự nhé!
1. Sắp xếp dữ liệu có kiểu khác nhau
Thử tưởng tượng: bạn sắp xếp một bảng theo một cột mà trong đó vừa có số vừa có chuỗi. PostgreSQL sẽ cố giúp bạn, nhưng kết quả có thể làm bạn bất ngờ đấy. Ví dụ bạn có một bảng mà value là text:
| id | value |
|---|---|
| 1 | 10 |
| 2 | 2 |
| 3 | apple |
| 4 | 20 |
Và bạn viết truy vấn:
SELECT *
FROM mixed_data
ORDER BY value;
Kết quả mong đợi? Có thể là: 2, 10, 20, apple? Không đâu, PostgreSQL sẽ sắp xếp chuỗi theo thứ tự từ điển/abc, và kết quả sẽ là: 10, 2, 20, apple.
Làm sao tránh lỗi này?
Nếu bạn biết cột text của mình thực ra chứa số, hãy ép kiểu nó sang số trước khi sắp xếp:
SELECT * FROM mixed_data ORDER BY value::INT;
Bây giờ kết quả sẽ là: 2, 10, 20.
Nhưng nhớ cẩn thận: nếu trong cột có chuỗi không chuyển được sang số, truy vấn sẽ báo lỗi đó nha!
2. Chỉ định nhiều cột để sắp xếp
Một lỗi điển hình — quên thứ tự ưu tiên khi sắp xếp theo nhiều cột. Ví dụ, bạn muốn sắp xếp sinh viên theo họ, rồi theo tuổi, nhưng lại đảo thứ tự:
| id | last_name | age |
|---|---|---|
| 1 | Lin | 18 |
| 2 | Lin | 20 |
| 3 | Song | 19 |
Truy vấn của bạn:
-- Sắp xếp sai
SELECT *
FROM students
ORDER BY age, last_name;
Kết quả:
| id | last_name | age |
|---|---|---|
| 1 | Lin | 18 |
| 3 | Song | 19 |
| 2 | Lin | 20 |
Trong trường hợp này PostgreSQL sẽ sắp xếp sinh viên theo tuổi trước, rồi mới đến họ. Không đúng ý bạn lắm nhỉ?
Truy vấn đúng:
SELECT *
FROM students
ORDER BY last_name, age;
Kết quả:
| id | last_name | age |
|---|---|---|
| 1 | Lin | 18 |
| 2 | Lin | 20 |
| 3 | Song | 19 |
Bây giờ sắp xếp sẽ theo họ trước, trong từng họ thì theo tuổi. Chuẩn luôn!
3. Sắp xếp với các hướng khác nhau
Đôi khi bạn cần sắp xếp nhiều cột với các hướng khác nhau. Ví dụ, sắp xếp sản phẩm theo category (tăng dần), trong mỗi category thì theo price (giảm dần). Lỗi là khi bạn quên chỉ định hướng cho cột thứ hai:
| id | category | price |
|---|---|---|
| 1 | Electronics | 99.99 |
| 2 | Electronics | 199.99 |
| 3 | Furniture | 299.99 |
| 4 | Furniture | 199.99 |
Truy vấn của bạn:
-- Sắp xếp sai
SELECT *
FROM products
ORDER BY category, price;
Kết quả: giá trong từng category sẽ tăng dần, nhưng bạn lại muốn giảm dần cơ mà.
Truy vấn đúng:
SELECT *
FROM products
ORDER BY category ASC, price DESC;
Lỗi khi định dạng
4. Dùng CONCAT() sai cách
Giả sử bạn muốn ghép tên và họ thành một chuỗi, nhưng vội quá lại quên thêm dấu cách giữa chúng:
| id | first_name | last_name |
|---|---|---|
| 1 | John | Doe |
| 2 | Jane | Smith |
Truy vấn của bạn:
SELECT
CONCAT(first_name, last_name) AS full_name
FROM employees;
Kết quả:
| full_name |
|---|
| JohnDoe |
| JaneSmith |
Làm sao sửa?
Thêm dấu cách giữa tên và họ nhé:
SELECT CONCAT(first_name, ' ', last_name) AS full_name FROM employees;
Bây giờ nhìn sẽ đẹp hơn nhiều:
| full_name |
|---|
| John Doe |
| Jane Smith |
5. Lỗi khi dùng CAST()
Giả sử bạn muốn chuyển ngày sang chuỗi cho đẹp, nhưng lại quên chỉ định định dạng:
| id | event_date |
|---|---|
| 1 | 2023-01-15 |
Truy vấn của bạn:
-- Chuyển đổi sai
SELECT
CAST(event_date AS TEXT)
FROM events;
Kết quả: ngày sẽ thành dạng YYYY-MM-DD, không phải lúc nào cũng tiện cho người dùng đâu.
Làm sao sửa?
Dùng hàm TO_CHAR() để chỉ định định dạng:
SELECT
TO_CHAR(event_date, 'DD-MM-YYYY') AS formatted_date
FROM events;
Bây giờ ngày sẽ hiển thị dạng 15-01-2023.
6. Lỗi khi dùng DISTINCT
DISTINCT — công cụ mạnh để lấy giá trị duy nhất, nhưng đôi khi lại dùng sai. Ví dụ, bạn muốn lấy danh sách tên nhân viên duy nhất:
SELECT DISTINCT first_name, last_name
FROM employees;
Nhìn qua thì truy vấn ổn, nhưng nếu hai nhân viên trùng tên và họ, họ sẽ chỉ hiện một dòng, dù là hai người khác nhau.
Ví dụ dữ liệu:
| id | first_name | last_name |
|---|---|---|
| 1 | Alex | Lin |
| 2 | Maria | Chi |
| 3 | Alex | Lin |
Kết quả truy vấn:
| first_name | last_name |
|---|---|
| Alex | Lin |
| Maria | Chi |
Làm sao tránh lỗi?
Thêm khóa chính để đảm bảo duy nhất nhé:
SELECT DISTINCT ON (id) first_name, last_name
FROM employees;
Kết quả truy vấn với DISTINCT ON (id):
| id | first_name | last_name |
|---|---|---|
| 1 | Alex | Lin |
| 2 | Maria | Chi |
| 3 | Alex | Lin |
Làm sao tránh lỗi?
Làm việc với dữ liệu cần chú ý từng chi tiết nhỏ. Để tránh các lỗi trên:
Kiểm tra kiểu dữ liệu: đảm bảo các hàm bạn dùng hỗ trợ đúng kiểu dữ liệu của cột.
Kiểm tra thứ tự sắp xếp: chắc chắn các cột được chỉ định đúng thứ tự. Đừng quên hướng sắp xếp ASC, DESC nhé.
Test truy vấn với dữ liệu nhỏ: sẽ giúp bạn phát hiện lỗi sớm hơn.
Đừng quên đọc tài liệu PostgreSQL: sẽ giúp bạn giải đáp các câu hỏi khó về hàm và cách dùng. Đây là link: tài liệu chính thức PostgreSQL.
Bây giờ bạn đã sẵn sàng chiến mọi thử thách về định dạng và sắp xếp rồi đó! Tiếp tục thôi nào.
GO TO FULL VERSION