SELECT
customer_id,
SUM(order_amount) AS total_amount
FROM
orders
WHERE
status = 'paid'
GROUP BY
customer_id
ORDER BY
total_amount DESC,
customer_id ASC;
(안내: 제공된 스키마가 없어 테이블명은 `orders`, 고객 ID 열은 `customer_id`, 주문 금액 열은 `order_amount`, 상태 열은 `status`로 가정하여 작성했습니다.)
절별 설명
- `SELECT customer_id, SUM(order_amount) AS total_amount`: 고객별로 그룹화하기 위한
customer_id와 결제 금액의 합계를 구하기 위해 SUM(order_amount)를 사용했습니다. (요청하지 않은 추가 집계 열은 넣지 않았습니다.) - `FROM orders`: 주문 정보를 담고 있는 기본 테이블을 지정합니다.
- `WHERE status = 'paid'`: 주문 상태가 'paid'(결제 완료)인 데이터만 먼저 필터링합니다.
- `GROUP BY customer_id`: 고객 단위로 행을 집계합니다.
- `ORDER BY total_amount DESC, customer_id ASC`: 합계 금액이 큰 순서대로(내림차순) 정렬하고, 금액이 같은 동률 고객이 발생할 경우
customer_id 기준 오름차순으로 정렬하여 순서를 안정적으로 고정합니다.
작은 입력 데이터 및 예상 결과 예시
입력 데이터 (orders 테이블)
| order_id | customer_id | status | order_amount |
|---|
| 101 | C001 | paid | 10000 |
| 102 | C002 | paid | 15000 |
| 103 | C001 | pending | 5000 |
| 104 | C001 | paid | 5000 |
| 105 | C002 | paid | 15000 |
| 106 | C003 | paid | 30000 |
예상 결과표
| customer_id | total_amount |
|---|
| C002 | 30000 |
| C003 | 30000 |
| C001 | 15000 |
계산 및 결과 대조 설명
- `WHERE status = 'paid'` 필터링 결과:
103번(pending) 주문을 제외한 101, 102, 104, 105, 106번 주문이 대상이 됩니다. - 고객별 합계 계산 (`GROUP BY`):
- C001: 101번(10000) + 104번(5000) = 15000
- C002: 102번(15000) + 105번(15000) = 30000
- C003: 106번(30000) = 30000
- 정렬 및 동률 처리 (`ORDER BY`):
total_amount 기준 내림차순 정렬 시 C002와 C003이 30000으로 동률이 발생합니다.- 두 번째 정렬 조건인
customer_id ASC에 따라 알파벳 순서가 앞서는 C002가 먼저 배치되고, 그 뒤에 C003이 배치됩니다. - 마지막으로 합계가 15000인 C001이 위치하여 예상 결과표의 행 순서와 일치하게 됩니다.
성능 확인 지점
status 열과 customer_id 열에 복합 인덱스(status, customer_id)가 생성되어 있다면, 조건 필터링과 그룹화 작업을 더 효율적으로 처리하는지 실행 계획을 통해 확인할 수 있습니다.
의견 보내기