정렬이랑 포맷팅은 당연히 유용하고 자주 쓰는 기능이지. 근데 가끔 실수로 헷갈려서 이상한 결과가 나올 때가 있어. 우리 같이 자주 하는 실수들 짚어보고, 데이터가 항상 깔끔하게 원하는 순서로 나오게 해보자!
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. 여러 컬럼 정렬할 때 순서 실수
여러 컬럼으로 정렬할 때 우선순서 헷갈려서 실수하는 경우 많아. 예를 들어 학생을 성(last_name)으로 먼저, 그 다음 나이(age)로 정렬하고 싶은데 순서를 반대로 썼다고 해보자:
| 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 |
이런 실수 피하려면?
프라이머리 키(id)를 같이 써서 유니크하게 만들어줘:
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 |
실수 피하는 방법?
데이터 다룰 때는 디테일에 신경 써야 해. 위에서 말한 실수들 피하려면:
데이터 타입 꼭 확인하기: 함수가 컬럼 타입이랑 맞는지 체크해.
정렬 순서 확인하기: 컬럼 순서 제대로 썼는지, ASC, DESC 방향도 잊지 말고!
작은 데이터로 쿼리 테스트하기: 미리 실수 잡을 수 있어.
PostgreSQL 공식 문서 참고하기: 함수나 사용법 헷갈릴 때 도움돼. 여기 링크: PostgreSQL 공식 문서.
이제 포맷팅이랑 정렬 관련된 어떤 문제도 자신 있게 해결할 수 있을 거야! 계속 달려보자~
GO TO FULL VERSION