[내일배움캠프] SQL/Python 코드카타

sleekstar·2025년 5월 30일

SQL 코드카타

문제 1.

재구매가 일어난 상품과 회원 리스트 구하기

POINT

'동일한' 회원이 '동일한' 상품을 재구매한 데이터를 추출.
USER_IDPRODUCT_ID가 겹치는 ROW를 추출해야 할 것.

구글링을 하다가 중복 값을 찾는 쿼리를 발견하고 일단 적용해봤는데, 정답이었다.

정답

SELECT 
    USER_ID,
    PRODUCT_ID
FROM ONLINE_SALE
GROUP BY USER_ID, PRODUCT_ID
HAVING COUNT(*) > 1
ORDER BY USER_ID ASC, PRODUCT_ID DESC;

✅ GROUP BY 여러 컬럼: 어떻게 작동하나?
(USER_ID, PRODUCT_ID) 의 조합이 동일한 행들끼리 그룹화
한 회원이 같은 상품을 여러 번 구매했는지 파악 가능

✅ HAVING COUNT(* ) > 1의 역할
그룹별로 구매 횟수가 2번 이상인 경우만 필터링

문제 2.

조건에 맞는 사용자 정보 조회하기

QUESTION

WHERE COUNT(B.WRITER_ID) >= 3 은 안될까?

  • COUNT는 그룹화된 결과를 만든 뒤에 계산됨.
  • WHERE는 그룹화 전에 필터를 하므로 COUNT()가 동작하지 않는다
구문 위치역할집계 함수 사용 가능 여부
WHEREGROUP BY 이전에, 행 필터링COUNT(), SUM() 불가능
HAVINGGROUP BY 이후에, 그룹 필터링COUNT(), AVG() 등 가능

정답
SELECT 
    U.USER_ID,
    U.NICKNAME,
    CONCAT(U.CITY,' ', U.STREET_ADDRESS1, ' ', U.STREET_ADDRESS2) AS '전체주소',
    CONCAT(SUBSTR(TLNO, 1, 3),'-',SUBSTR(TLNO, 4, 4),'-',SUBSTR(TLNO, 8, 4)) AS '전화번호'
FROM USED_GOODS_BOARD B LEFT JOIN USED_GOODS_USER U
    ON B.WRITER_ID = U.USER_ID
GROUP BY B.WRITER_ID
HAVING COUNT(B.WRITER_ID) >=3
ORDER BY USER_ID DESC;

문제 3.

자동차 대여 기록에서 대여중 / 대여 가능 여부 구분하기

IDEA

일단 자동차 대여 기록을 보니, CAR_ID가 겹치는 경우가 많았다. 같은 자동차를 빌렸다가, 반납했다가, 빌렸다가 하니까 당연한 결과다.
그래서 이런 중복되는 값을 어떻게 처리할지가 포인트인 것 같다.

SUBQUERY 이용

  1. 먼저 대여 중인 자동차를 찾는다.
SELECT 
	CAR_ID
FROM CAR_RENTAL_COMPANY_RENTAL_HISTORY
WHERE '2022-10-16' BETWEEN START_DATE AND END_DATE
  1. 전체 차량 목록 만들고 '대여중' / '대여 가능' 표시

=> 두 쿼리를 결합하자!

정답

SELECT
	CAR_ID,
    IF(
    	CAR_ID IN (
        	SELECT CAR_ID
            FROM CAR_RENTAL_COMPANY_RENTAL_HISTORY
            WHERE '2022-10-16' BETWEEN START_DATE AND END_DATE
            ), 
            '대여중',
            '대여 가능'
       ) AS AVAILABILITY
FROM CAR_RENTAL_COMPANY_RENTAL_HISTORY
GROUP BY CAR_ID
ORDER BY CAR_ID DESC;

IF(조건, 참일 때 값, 거짓일 때 값)

Python 코드카타

문제 1.

핸드폰 번호 가리기

idea

일단 phone_number를 리스트로 만들고, for 반복문을 이용해 끝에서부터 4자리만 남기고 전부 *로 바꾸면 될 것 같다.

처음 작성한 코드

def solution(phone_number):
    answer = list(phone_number)
    for i in range(len(answer)-4):
        answer[i] = '*'
    answer = ''.join(answer)
    return answer

''.join은 선택된 요소들을 하나로 이어주는 문법이다. ''안에 다른 문자나 공백을 넣ㅇ르 수도 있다.

try

조금 더 코드를 깨끗하게 만들 순 없을까?
반복문을 이용하지 않아도 될 것 같은데...
하는 마음에 replace를 사용해 보았다.

버전 1(오답)

solution(phone_number):
    phone_number = phone_number.replace(phone_number[:-4], '*')
    return phone_number

그런데 이러면 phone_number[:-4]까지 * 하나로 처리된다.
즉, '01033334444'를 입력하면 '* 4444'가 된다.

그렇다면 그냥 len(phone_number)-4 까지 다 '* '로 처리하고, phone_number[-4:]와 이어주는 건 어떨까?

버전 2(정답)

solution(phone_number):
    phone_number = phone_number.replace(phone_number[:-4], '*')
    return phone_number
profile
기록용

0개의 댓글