본문 바로가기
SQL

실전 문제 풀이 (6)

by 바른곰의 SQL천국 2025. 8. 19.

문제 1 — 고객별 최근 주문 2건 조회

CREATE TABLE orders_p1 (
  order_id INT,
  customer_id INT,
  order_date DATE,
  amount INT
);

INSERT INTO orders_p1 VALUES
(101, 1, '2025-07-01', 100),
(102, 1, '2025-07-05', 150),
(103, 1, '2025-07-05', 200),
(201, 2, '2025-06-01', 50),
(202, 2, '2025-07-10', 75),
(301, 3, '2025-05-20', 300);

 

목표

  • 각 고객별로 최근 주문일 순으로 2건만 출력
  • 같은 날짜 주문은 order_id 오름차순 정렬
  • 출력: customer_id, order_id, order_date, amount
WITH date_table AS (
  SELECT
    *,
    ROW_NUMBER() OVER (
      PARTITION BY customer_id
      ORDER BY order_date DESC, order_id
      ) AS rn
  FROM orders_p1
  )
  
SELECT
  customer_id,
  order_id,
  order_date,
  amount
FROM date_table
WHERE rn <= 2

 

 

 

문제 2 — 카테고리별 매출 상위 1개 상품

CREATE TABLE products (
  product_id INT,
  category VARCHAR(50)
);

CREATE TABLE sales (
  sale_id INT,
  product_id INT,
  quantity INT,
  price INT
);

INSERT INTO products VALUES
(1, '전자'), (2, '전자'), (3, '가구'), (4, '가구');

INSERT INTO sales VALUES
(1, 1, 3, 1000),
(2, 1, 2, 1000),
(3, 2, 5, 500),
(4, 3, 1, 2000),
(5, 4, 3, 1000),
(6, 4, 2, 1000);

 

목표

  • products와 sales를 조인
  • 카테고리별 매출합계가 가장 높은 상품 1개 출력
  • 동점이면 상품ID 오름차순
  • 출력: category, product_id, total_sales
WITH join_table AS (
  SELECT
    s.product_id,
    p.category,
    sale_id,
    quantity,
    price
  FROM sales s
  JOIN products p
    ON s.product_id = p.product_id
),

rank_table AS (
  SELECT
    *,
    ROW_NUMBER() OVER (
      PARTITION BY category
      ORDER BY price * quantity DESC, product_id
      ) AS rn
  FROM join_table
  )
  
SELECT
  category,
  product_id,
  quantity,
  price
FROM rank_table
WHERE rn = 1

 

 

 

문제 3 — 전월 대비 매출 증가율

CREATE TABLE monthly_sales (
  month DATE,
  revenue INT
);

INSERT INTO monthly_sales VALUES
('2025-01-01', 1000),
('2025-02-01', 1200),
('2025-03-01', 1100),
('2025-04-01', 1500);

 

목표

  • monthly_sales 테이블에서 각 달의 매출과 전월 대비 증가율(%) 계산
  • 증가율 = (이번달 - 지난달) / 지난달 * 100
  • 첫 달은 증가율 NULL
  • 출력: month, revenue, pct_change
WITH grow_table AS (
  SELECT
    month,
    revenue,
    (revenue - LAG(revenue) OVER (ORDER BY month)) / LAG(revenue) OVER (ORDER BY month) * 100 AS pct_change
  FROM monthly_sales
)

SELECT
  month,
  revenue,
  pct_change
FROM grow_table

 

 

 

문제 4 — 직원별 부서 평균급여 대비 차이

CREATE TABLE employees (
  emp_id INT,
  dept_id INT,
  salary INT
);

INSERT INTO employees VALUES
(1, 10, 5000),
(2, 10, 6000),
(3, 20, 7000),
(4, 20, 6500),
(5, 20, 8000);

 

목표

  • employees 테이블에서 같은 부서(dept_id) 평균급여를 구하고,
    직원의 급여와 평균급여 차이 계산
  • 출력: emp_id, dept_id, salary, avg_salary, salary_diff
WITH avg_table AS (
  SELECT
    *,
    AVG(salary) OVER (
      PARTITION BY dept_id
      ) AS avg_salary
  FROM employees
  )
  
SELECT
  emp_id,
  dept_id,
  salary,
  avg_salary,
  salary - avg_salary AS salary_diff
FROM avg_table

 

 

 

문제 5 — 연속 로그인 일수 구하기

CREATE TABLE user_logins (
  user_id INT,
  login_date DATE
);

INSERT INTO user_logins VALUES
(1, '2025-07-01'),
(1, '2025-07-02'),
(1, '2025-07-03'),
(1, '2025-07-05'),
(2, '2025-06-10'),
(2, '2025-06-11'),
(2, '2025-06-13');

 

목표

  • user_logins에서 각 유저별로 가장 긴 연속 로그인 일수 계산
  • 연속은 하루씩 차이날 때로 판단
  • 출력: user_id, max_streak
WITH count_table AS (
  SELECT
    user_id,
    login_date,
    DATE_SUB(login_date, INTERVAL ROW_NUMBER() OVER (PARTITION BY user_id ORDER BY login_date) DAY) AS criterion
  FROM user_logins
  ),

group_table AS (
  SELECT 
    user_id,
    COUNT(*) AS continue_login_count
  FROM count_table
  GROUP BY user_id, criterion
  )

SELECT 
 user_id,
 MAX(continue_login_count)
FROM group_table
GROUP BY user_id

 

 

 


 

2번 문제에서 total_sales를 구해서 그것을 기준으로 계산해야 했지만, CTE를 한번 더 사용하기에는 코드가 길어질 것 같아서 total_sales를 안구하고 문제를 풀었더니 GPT가 귀신같이 잡아냈다... 무섭다...

'SQL' 카테고리의 다른 글

실전 문제 풀이 (7)  (0) 2025.08.21
실전 문제 풀이 (5)  (5) 2025.08.17
실전 문제 풀이 (4)  (3) 2025.08.15
실전 문제 풀이 (3)  (2) 2025.08.13
실전 문제 풀이 (2)  (3) 2025.08.11