[SQL] ROW_NUMBER()로 고객별 최신 주문 한 건 찾기

차곡코딩·4일 전

SQL · 집계 쿼리

목록 보기
4/5

고객별 가장 최근 주문의 날짜뿐 아니라 주문 번호와 금액도 함께 필요할 때가 있습니다. 날짜에 MAX()를 적용하는 것만으로는 그 날짜에 해당하는 행의 다른 열까지 자동으로 선택되지 않아요.

이번 예제에서는 고객마다 주문을 최신순으로 정렬해 번호를 붙인 뒤 첫 행을 선택하겠습니다. 문법은 MySQL 8.4 기준이며, 예제 결과는 SQLite에서 검증합니다.

같은 시각에 주문한 경우도 정해 둡니다

주문 시각이 같으면 주문 번호가 큰 행을 선택한다는 규칙을 사용하겠습니다. 주문 번호는 기본 키이므로 이 기준까지 적용하면 순서가 하나로 정해집니다. 이것은 동률 처리 규칙이지 큰 번호가 실제로 더 늦게 주문되었다는 증명은 아닙니다.

CREATE TABLE orders (
    order_id INTEGER PRIMARY KEY,
    customer_id INTEGER NOT NULL,
    ordered_at DATETIME NOT NULL,
    amount INTEGER NOT NULL
);
INSERT INTO orders VALUES
    (101, 1, '2026-09-27 09:00:00', 10000),
    (102, 1, '2026-09-28 10:00:00', 20000),
    (103, 1, '2026-09-28 10:00:00', 15000),
    (201, 2, '2026-09-27 11:00:00', 7000);

고객별로 번호를 다시 매겨요

WITH ranked AS (
    SELECT order_id, customer_id, ordered_at, amount,
           ROW_NUMBER() OVER (
               PARTITION BY customer_id
               ORDER BY ordered_at DESC, order_id DESC
           ) AS rn
    FROM orders
)
SELECT order_id, customer_id, ordered_at, amount
FROM ranked
WHERE rn = 1
ORDER BY customer_id;
order_idcustomer_idordered_atamount
10312026-09-28 10:00:0015000
20122026-09-27 11:00:007000

PARTITION BY는 번호를 매길 구간을 고객별로 나눕니다. 그 안에서 주문 시각과 번호를 내림차순으로 정렬하고 ROW_NUMBER()가 1부터 번호를 붙여요. 바깥 쿼리는 1번 행만 남깁니다.

윈도 함수 안의 ORDER BY는 번호를 붙일 기준입니다. 최종 결과의 표시 순서는 바깥쪽 ORDER BY로 별도 지정했습니다.

MAX를 각각 구하면 서로 다른 주문이 섞일 수 있어요

SELECT customer_id,
       MAX(ordered_at) AS latest_time,
       MAX(amount) AS max_amount
FROM orders
GROUP BY customer_id
ORDER BY customer_id;
customer_idlatest_timemax_amount
12026-09-28 10:00:0020000
22026-09-27 11:00:007000

이 쿼리는 최신 시각과 최대 금액을 각각 구합니다. 선택 규칙에 따른 103번 주문의 금액은 15000인데, 최대 금액은 102번 주문의 20000입니다. 두 집계 결과가 같은 원본 행에서 왔다고 볼 수는 없어요.

한 건과 공동 최신은 다른 요구입니다

같은 최신 시각의 주문을 모두 반환해야 한다면 지금의 한 건 선택 규칙은 맞지 않습니다. 시각만 기준으로 순위를 매기는 RANK() 등 다른 방법을 검토해야 해요. 또한 주문이 없는 고객은 orders 테이블에 행이 없으므로 이 결과에 나타나지 않습니다.

이 예제는 모든 주문 시각이 같은 시간 기준으로 저장되며 NULL이 없다고 가정합니다. 실제 데이터에서는 시간대와 누락 값의 처리 기준도 함께 확인해야 합니다.

참고

profile
비전공자의 개발 성장 기록. 바이브코딩 프리랜서 경험부터 Python·SQL·AI 서비스 개발까지

0개의 댓글