본문 바로가기
Data Science/SQL

[SQL/오답] 첫 해(First Year)의 상세 기록 추출: 집계와 행 데이터 매칭의 정석 (LeetCode1070 Medium)

by 에르모사 쩐뉴 2026. 2. 7.

1070. Product Sales Analysis III; WHERE-IN, 중첩 서브쿼리

https://leetcode.com/problems/product-sales-analysis-iii/

 

1. Problem

각 제품(product_id)별로 가장 처음 판매된 연도를 찾고, 그 연도에 발생한 모든 판매 기록(수량, 가격)을 출력해야 한다.

  • 핵심 과제: 단순히 '최소 연도'를 구하는 것에 그치지 않고, 그 연도에 해당하는 quantityprice를 유실이나 왜곡 없이 정확히 가져오는 것이다.

2. Solution: 다중 컬럼 서브쿼리를 이용한 행 특정

MIN(year)를 구하는 서브쿼리를 만들고, 이 결과(ID, Year) 쌍과 일치하는 원본 행을 IN 연산자로 필터링한다.

3. Takeaway: 집계 함수와 일반 컬럼의 동시 조회 주의점 (객관적 분석)

  • GROUP BY의 함정 (유진 님의 오답 분석):
    • 오답: SELECT product_id, MIN(year), quantity, price FROM Sales GROUP BY product_id
    • 원인: GROUP BY를 사용하면 SQL은 그룹당 단 하나의 행만 반환하려 한다. 이때 MIN(year)는 정확히 계산되지만, 그룹화되지 않은 quantityprice는 해당 그룹 내의 여러 행 중 임의의 행에서 가져오게 된다.
    • 결과: 2008년이 첫 해인데 가격은 2009년 기록이 나오는 식의 데이터 부정합이 발생한다. (ANSI SQL 표준에서는 이런 쿼리 자체를 에러로 처리한다.)
  • 다중 컬럼 IN 연산자의 객관적 우수성:
    • (product_id, year)를 하나의 묶음(Tuple)으로 비교함으로써, "특정 제품의 특정 연도"라는 조건을 정확히 만족하는 행만 뽑아낼 수 있다.
    • 만약 첫 해에 판매 기록이 두 건 이상(동일 연도 중복 판매)이라면, 두 기록 모두 정상적으로 출력된다는 장점이 있다.
Table: Sales

+-------------+-------+
| Column Name | Type  |
+-------------+-------+
| sale_id     | int   |
| product_id  | int   |
| year        | int   |
| quantity    | int   |
| price       | int   |
+-------------+-------+
(sale_id, year) is the primary key (combination of columns with unique values) of this table.
Each row records a sale of a product in a given year.
A product may have multiple sales entries in the same year.
Note that the per-unit price.

Write a solution to find all sales that occurred in the first year each product was sold.

For each product_id, identify the earliest year it appears in the Sales table.

Return all sales entries for that product in that year.

Return a table with the following columns: product_id, first_year, quantity, and price.
Return the result in any order.

 

Example 1:

Input: 
Sales table:
+---------+------------+------+----------+-------+
| sale_id | product_id | year | quantity | price |
+---------+------------+------+----------+-------+ 
| 1       | 100        | 2008 | 10       | 5000  |
| 2       | 100        | 2009 | 12       | 5000  |
| 7       | 200        | 2011 | 15       | 9000  |
+---------+------------+------+----------+-------+

Output: 
+------------+------------+----------+-------+
| product_id | first_year | quantity | price |
+------------+------------+----------+-------+ 
| 100        | 2008       | 10       | 5000  |
| 200        | 2011       | 15       | 9000  |
+------------+------------+----------+-------+

 

1. 정답 

SELECT product_id, year AS first_year, quantity, price
FROM Sales
WHERE (product_id, year) IN (
    -- 1단계: 제품별로 가장 작은(첫 번째) 연도 쌍을 구한다
    SELECT product_id, MIN(year)
    FROM Sales
    GROUP BY product_id
);

 

2. 오답 쿼리

product_id별로 가장 이른 연도는 잘 찾아내겠지만, 그때의 quantity와 price가 '진짜 그 해의 데이터'라는 보장이 없다. SQL의 GROUP BY는 묶이지 않은 나머지 컬럼들에 대해 "아무 값이나" 보여주는 경향이 있다.

SELECT product_id, MIN(year) AS first_year, quantity, price
FROM Sales
GROUP BY product_id;