작성
·
16
답변 2
1
안녕하세요. kokodae.ko 님.
질문 주셔서 감사합니다. 질문에 답을 드리자면..
24번 문제는 아래와 같고, 문제에서 요구하는 것은 '연속된 3일 이상' 입니다.
24. 아래의 테이블에서 연속된 3일 이상 결제금액이 10만원을 초과한 고객을 찾으려고 한다. 가장 적절한 SQL문은?
문제에서 요구하는 '3일 이상' 이라는 기준으로 접답을 찾으면 3번입니다.
보기 1번은 3일 '이상' 이라는 기준을 충족하기 어렵습니다. 작성된 쿼리는 정확히 3일을 기준으로 데이터를 조회하게 되어 있습니다. 보기 3번은 3일 이상이라는 조건을 충족합니다.
물론 제시된 데이터만 가지고 보면, 1번도 답이 맞는 것 같다고 할 수 있습니다. 하지만 문제는 가장 적절한 것을 찾는 것이기 때문에 보기 중에서 가장 적절한 것을 선택하는 것이 좋습니다.
아래는 24번 문제의 실습 데이터와 쿼리입니다. 문제에서 제시된 데이터 외에 추가로 몇 건을 더 입력합니다. 실습 해보시면, 이해가 더 잘 되실 겁니다.
CREATE TABLE PAYMENT (
CUSTOMER_ID VARCHAR(10) NOT NULL,
PAYMENT_DATE DATE NOT NULL,
AMOUNT INT NOT NULL,
PRIMARY KEY (CUSTOMER_ID, PAYMENT_DATE)
);
INSERT INTO PAYMENT (CUSTOMER_ID, PAYMENT_DATE, AMOUNT) VALUES
('A001', DATE '2024-01-01', 120000),
('A001', DATE '2024-01-02', 150000),
('A001', DATE '2024-01-03', 130000), -- A001은 3일 연속 (1/1~1/3) 조건을 만족
('A001', DATE '2024-01-04', 80000), -- 10만원 이하로 연속 종료
('A002', DATE '2024-01-01', 110000),
('A002', DATE '2024-01-02', 90000), -- 10만원 이하로 연속 실패
('A002', DATE '2024-01-03', 120000),
('A003', DATE '2024-01-05', 110000),
('A003', DATE '2024-01-07', 120000), -- 1일씩 간격이 있어 연속 실패
('A003', DATE '2024-01-09', 130000),
('A004', DATE '2024-02-10', 105000),
('A004', DATE '2024-02-11', 106000),
('A004', DATE '2024-02-12', 107000),
('A004', DATE '2024-02-13', 108000); -- A004는 4일 연속 (1/10~1/13) 조건을 만족
-- DBMS에 따라 DATE 'YYYY-MM-DD' 형식이 지원되지 않을 경우 TO_DATE('YYYY-MM-DD', 'YYYY-MM-DD') 등을 사용해야 할 수 있습니다.
-- 1번 보기 : 정확하게 3일간 10만 이상인 데이터를 찾음. 문제에서는 3일 이상을 요구하고 있음
SELECT DISTINCT P1.CUSTOMER_ID
FROM PAYMENT P1
JOIN PAYMENT P2 ON P1.CUSTOMER_ID = P2.CUSTOMER_ID
JOIN PAYMENT P3 ON P2.CUSTOMER_ID = P3.CUSTOMER_ID
WHERE P2.PAYMENT_DATE = P1.PAYMENT_DATE + 1
AND P3.PAYMENT_DATE = P2.PAYMENT_DATE + 1
AND P1.AMOUNT > 100000
AND P2.AMOUNT > 100000
AND P3.AMOUNT > 100000;
-- 2번 보기 : 10만 이상인 고객 중 거래가 3건 이상인 고객 아이디를 반환함
SELECT CUSTOMER_ID
FROM PAYMENT
WHERE AMOUNT > 100000
GROUP BY CUSTOMER_ID
HAVING COUNT(*) >= 3;
-- 3번 : 연속된 날짜를 그룹화 하는 '차이 분석 기법' 방식
-- With 내부의 Select 구문을 실행하면, 연속된 날짜인 경우 동일한 GRP 날짜가 생깁니다. 연속되지 않은 경우 동일한 GRP 날짜가 생기지 않고요.
WITH CONSECUTIVE_DAYS AS (
SELECT CUSTOMER_ID,
PAYMENT_DATE,
AMOUNT,
ROW_NUMBER() OVER (PARTITION BY CUSTOMER_ID ORDER BY PAYMENT_DATE) AS RN,
PAYMENT_DATE - ROW_NUMBER() OVER (PARTITION BY CUSTOMER_ID ORDER BY PAYMENT_DATE) AS GRP
FROM PAYMENT
WHERE AMOUNT > 100000
)
SELECT DISTINCT CUSTOMER_ID
FROM (
SELECT CUSTOMER_ID, GRP, COUNT(*) AS CNT
FROM CONSECUTIVE_DAYS
GROUP BY CUSTOMER_ID, GRP
HAVING COUNT(*) >= 3
);
-- 4번: 3일 이상 연속 조건을 확인하기 어려움. 금액이 10만 이상인 것 기준으로 조회
SELECT DISTINCT CUSTOMER_ID
FROM (
SELECT CUSTOMER_ID,
AMOUNT,
LAG(AMOUNT, 1) OVER (PARTITION BY CUSTOMER_ID ORDER BY PAYMENT_DATE) AS PREV_AMOUNT,
LAG(AMOUNT, 2) OVER (PARTITION BY CUSTOMER_ID ORDER BY PAYMENT_DATE) AS PREV2_AMOUNT
FROM PAYMENT
)일
WHERE AMOUNT > 100000
AND PREV_AMOUNT > 100000
AND PREV2_AMOUNT > 100000;
0
안녕하세요, 인프런 AI 인턴입니다. kokodae.ko님.
해당 문제에서 1번 보기와 3번 보기에 대한 혼란이 있는 것 같습니다. SQL에서는 연속된 날짜를 처리하는 방식에 대한 여러 접근이 있을 수 있는데, 질문해주신 문제는 그 중에서도 연속된 3일을 구별하는 로직에 관한 것입니다.
1번 보기는 특정 조건을 만족할 수 있어 보이지만, 주어진 데이터와 문제에서 요구하는 조건 기반으로 최적의 해답인지는 고민해볼 필요가 있습니다. 3번 보기가 정답으로 선택된 이유는, 연속된 날짜를 기준으로 정확히 구별하고 그룹핑하여 문제의 요구를 충족하기 때문일 것입니다.
정확한 코드를 검토해 보지 않아 초기 설정에 따라 각각의 쿼리가 데이터를 처리하는 방식에서의 미묘한 차이가 있을 수 있습니다. 특히, SQL에서의 DATE
처리나 GROUP BY
연산은 데이터베이스에 따라 다르게 동작할 수 있습니다.
이와 관련해 보다 명확한 이해를 돕기 위해 다음의 유사한 질문과 답변을 참고해보시면 좋을 것 같습니다:
- 연속된 날짜 데이터 처리 SQL 질문
저는 질문자님의 이해를 돕고자 지식공유자님의 기존 답변을 참고하여 유사한 답변 링크를 추천해드리고 있습니다.
현재 베타 기능으로 답변이 만족스럽지 않을 수 있는 점 양해 부탁드립니다. 🙏
추가적으로 궁금한 점이 있으시면, 이어서 질문해 주세요. 곧 지식공유자께서 답변해 주실 것입니다.