排序跟格式化資料這件事,聽起來很直觀也很有用啦。但有時候一不小心就會搞混,結果出來超乎預期。來,我們一起拆解一下最常見的錯誤,讓你的資料永遠都漂漂亮亮、順順排好!
1. 不同型別資料的排序
想像一下:你在排序一個欄位,裡面有數字也有字串。PostgreSQL 當然會盡力幫你排,但結果可能會讓你傻眼。比如你有一個表格,value 是文字:
| id | value |
|---|---|
| 1 | 10 |
| 2 | 2 |
| 3 | apple |
| 4 | 20 |
然後你寫了這個查詢:
SELECT *
FROM mixed_data
ORDER BY value;
你以為結果會是 2, 10, 20, apple 嗎?錯啦,PostgreSQL 會用字典/字母順序來排,結果會是:10, 2, 20, apple。
怎麼避免這種錯誤?
如果你知道你的文字欄位其實是數字,排序前記得明確轉成數字:
SELECT * FROM mixed_data ORDER BY value::INT;
這樣結果就會是:2, 10, 20。
但要小心:如果欄位裡有不能轉成數字的字串,查詢會直接報錯喔!
2. 多欄位排序時順序搞錯
很常見的錯誤之一,就是多欄位排序時忘記排序優先順序。比如你想先用姓氏,再用年齡排學生,但順序寫反了:
| id | last_name | age |
|---|---|---|
| 1 | Lin | 18 |
| 2 | Lin | 20 |
| 3 | Song | 19 |
你的查詢:
-- 排序順序錯誤
SELECT *
FROM students
ORDER BY age, last_name;
結果:
| id | last_name | age |
|---|---|---|
| 1 | Lin | 18 |
| 3 | Song | 19 |
| 2 | Lin | 20 |
這樣 PostgreSQL 會先用年齡排,再用姓氏。這不是你想要的吧?
正確的查詢:
SELECT *
FROM students
ORDER BY last_name, age;
結果:
| id | last_name | age |
|---|---|---|
| 1 | Lin | 18 |
| 2 | Lin | 20 |
| 3 | Song | 19 |
這樣就會先用姓氏排,然後同姓的再用年齡排。這才是你要的!
3. 不同排序方向搞混
有時候你會想對不同欄位用不同的排序方向。比如商品要先按類別升序,再在每個類別裡按價格降序。如果你忘了寫第二個欄位的排序方向就會出錯:
| id | category | price |
|---|---|---|
| 1 | Electronics | 99.99 |
| 2 | Electronics | 199.99 |
| 3 | Furniture | 299.99 |
| 4 | Furniture | 199.99 |
你的查詢:
-- 排序方向錯誤
SELECT *
FROM products
ORDER BY category, price;
結果:每個類別裡的價格會是升序,但你可能想要降序。
正確的查詢:
SELECT *
FROM products
ORDER BY category ASC, price DESC;
格式化時的錯誤
4. 用 CONCAT() 時沒加分隔符號
假設你想把名字和姓氏合併成一個字串,但太趕忘了加個空格:
| id | first_name | last_name |
|---|---|---|
| 1 | John | Doe |
| 2 | Jane | Smith |
你的查詢:
SELECT
CONCAT(first_name, last_name) AS full_name
FROM employees;
結果:
| full_name |
|---|
| JohnDoe |
| JaneSmith |
怎麼修正?
加個空格在名字和姓氏中間:
SELECT CONCAT(first_name, ' ', last_name) AS full_name FROM employees;
這樣看起來就舒服多了:
| full_name |
|---|
| John Doe |
| Jane Smith |
5. 用 CAST() 時沒指定格式
假設你想把日期轉成字串好看一點,但忘了指定格式:
| id | event_date |
|---|---|
| 1 | 2023-01-15 |
你的查詢:
-- 轉換格式錯誤
SELECT
CAST(event_date AS TEXT)
FROM events;
結果:日期會變成 YYYY-MM-DD,但這不一定是你或用戶想要的格式。
怎麼修正?
用 TO_CHAR() 指定你要的格式:
SELECT
TO_CHAR(event_date, 'DD-MM-YYYY') AS formatted_date
FROM events;
這樣日期就會變成 15-01-2023 這種格式。
6. 用 DISTINCT 時的誤區
DISTINCT 超好用,可以抓出唯一值,但有時候會被誤用。比如你想抓出員工唯一的名字:
SELECT DISTINCT first_name, last_name
FROM employees;
看起來沒問題,但如果有兩個員工名字和姓氏都一樣,他們會被當成一個結果,雖然其實是不同人。
資料範例:
| id | first_name | last_name |
|---|---|---|
| 1 | Alex | Lin |
| 2 | Maria | Chi |
| 3 | Alex | Lin |
查詢結果:
| first_name | last_name |
|---|---|
| Alex | Lin |
| Maria | Chi |
怎麼避免這種錯誤?
加上主鍵,確保唯一性:
SELECT DISTINCT ON (id) first_name, last_name
FROM employees;
用 DISTINCT ON (id) 查詢的結果:
| id | first_name | last_name |
|---|---|---|
| 1 | Alex | Lin |
| 2 | Maria | Chi |
| 3 | Alex | Lin |
怎麼避免這些錯誤?
處理資料時,細節真的很重要。想避免上面那些坑:
檢查資料型別: 確認你用的 function 支援你欄位的型別。
檢查排序順序: 確認欄位順序寫對了,也別忘了 ASC、DESC 這些排序方向。
先用小資料測試查詢: 這樣可以早點發現 bug。
多看 PostgreSQL 官方文件: 有問題就查文件,裡面什麼都有。這裡有連結:PostgreSQL 官方文件。
現在你已經準備好面對所有格式化和排序的謎題啦!繼續加油!
GO TO FULL VERSION