티스토리 뷰

SQL 코드카타

Q56. 특정 옵션이 포함된 자동차 리스트 구하기

1. 문제 링크: https://school.programmers.co.kr/learn/courses/30/lessons/157343

2. 정답 코드:

SELECT
    CAR_ID,
    CAR_TYPE,
    DAILY_FEE,
    OPTIONS
FROM CAR_RENTAL_COMPANY_CAR
WHERE OPTIONS LIKE '%네비게이션%'
ORDER BY CAR_ID DESC;

 

Q57. 조건에 부합하는 중고거래 상태 조회하기

1. 문제 링크: https://school.programmers.co.kr/learn/courses/30/lessons/164672

2. 정답 코드:

SELECT
    BOARD_ID,
    WRITER_ID,
    TITLE,
    PRICE,
    CASE
        WHEN STATUS = 'SALE' THEN '판매중'
        WHEN STATUS = 'RESERVED' THEN '예약중'
        WHEN STATUS = 'DONE' THEN '거래완료'
    END AS STATUS
FROM USED_GOODS_BOARD
WHERE CREATED_DATE = '2022-10-05'
ORDER BY BOARD_ID DESC;

 

Q58. 취소되지 않은 진료 예약 조회하기

1. 문제 링크: https://school.programmers.co.kr/learn/courses/30/lessons/132204

2. 정답 코드:

SELECT
    a.APNT_NO,
    p.PT_NAME,
    p.PT_NO,
    a.MCDP_CD,
    d.DR_NAME,
    a.APNT_YMD
FROM APPOINTMENT AS a
JOIN PATIENT AS p
  ON a.PT_NO = p.PT_NO
JOIN DOCTOR AS d
  ON a.MDDR_ID = d.DR_ID
WHERE SUBSTR(a.APNT_YMD, 1, 10) = "2022-04-13"
  AND a.APNT_CNCL_YN = "N"
  AND a.MCDP_CD = "CS"
ORDER BY a.APNT_YMD ASC;

 

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

1. 문제 링크: https://school.programmers.co.kr/learn/courses/30/lessons/157340

2. 정답 코드:

SELECT
    DISTINCT CAR_ID,
    CASE
        WHEN CAR_ID IN (
            SELECT CAR_ID
            FROM CAR_RENTAL_COMPANY_RENTAL_HISTORY
            WHERE START_DATE <= '2022-10-16' AND END_DATE >= '2022-10-16'        
        ) THEN '대여중'
        ELSE '대여 가능'
    END AS AVAILABILITY
FROM CAR_RENTAL_COMPANY_RENTAL_HISTORY
ORDER BY CAR_ID DESC;

# 서브쿼리 사용하여 AVAILABILITY 컬럼 생성

SELECT
    DISTINCT CAR_ID,
    CASE
        WHEN START_DATE <= '2022-10-16' AND END_DATE >= '2022-10-16' THEN '대여중'
        ELSE '대여 가능'
    END AS AVAILABILITY
FROM CAR_RENTAL_COMPANY_RENTAL_HISTORY
ORDER BY CAR_ID DESC;

# 막히기 전까지 작성했던 내용

3. 오류 상황: CAR_ID 한개당 여러 개의 AVAILABILITY 값이 나옴('대여중', '대여 가능' 여러 개)

4. 시도 방법: Gemini를 활용하여 방법 찾아 봄

5. 최종 문제 해결 방법: 서브쿼리를 활용해서 '2022-10-16' 기준으로 차를 빌렸지만 반납하지 않은 CAR_ID를 따로 찾아 '대여중'으로 분류해줌


생성형 AI 답변 내용)

학교 도서관 대출 장부를 예로 들어서 설명해 줄게요.

우리 학교 도서관에 '해리포터 1권'이 한 권 있다고 상상해 보세요. 이 책의 대출 기록장(HISTORY)은 이렇게 적혀 있을 거예요.

책 번호 (CAR_ID) 빌린 날짜 (START) 반납 날짜 (END)
해리포터 2022-01-01 2022-01-05
해리포터 2022-10-15 2022-10-20

자, 오늘이 2022-10-16이라고 할 때, 이 책은 대여 중일까요? 네, 대여 중입니다.

 

1. 두 번째 코드의 실수 (기록장만 한 장씩 넘기기)

두 번째 코드는 기록장을 첫 페이지부터 한 장씩 넘기면서 혼자 중얼거리는 것과 같아요.

  • 첫 번째 기록을 보고: "어? 1월 기록이네? 오늘은 10월 16일이니까 이때는 대여 가능했겠네!" → [해리포터 : 대여 가능] 출력
  • 두 번째 기록을 보고: "오! 이건 오늘 날짜를 포함하네? 지금 대여 중이네!" → [해리포터 : 대여중] 출력

이렇게 되면 컴퓨터는 결과창에 [대여 가능] 한 번, [대여중] 한 번을 둘 다 써버려요. 우리는 지금 이 책을 빌릴 수 있는지 없는지 딱 하나만 알고 싶은데 말이죠.

 

2. 첫 번째 코드의 정답 (블랙리스트 확인하기)

첫 번째 코드는 아주 똑똑한 사서 선생님처럼 행동해요.

  • 먼저 명단을 뽑아요 (서브쿼리): "자, 오늘 날짜(10/16)에 책 안 가져오고 빌려 가고 있는 놈들(CAR_ID) 다 모여봐!" → [해리포터] 이름이 명단에 적힘.
  • 그다음 확인해요 (CASE + IN): 이제 도서관에 있는 모든 책 리스트를 봅니다.
    • "해리포터 책, 너 아까 만든 '안 가져온 놈들 명단'에 이름 있니?"
    • "있네! 그럼 넌 무조건 **'대여중'**이야."

과거에 1월에 빌렸건, 5월에 빌렸건 상관없어요. 오늘 날짜가 포함된 명단에 이름이 한 번이라도 올라가 있다면, 컴퓨터는 고민하지 않고 딱 한 줄로 '대여중'이라고 대답해 주는 거예요.

 

3. 핵심 요약

  • 두 번째 코드는: "과거의 너는 빌릴 수 있었고, 지금의 너는 빌릴 수 없어"라며 과거와 현재를 다 말해버리는 코드 (그래서 엉뚱한 '대여 가능' 줄이 생김)
  • 첫 번째 코드는: "과거는 모르겠고, 지금 명단에 이름 있으면 무조건 대여 중이야"라고 깔끔하게 결론 내는 코드

+

❌ 두 번째 코드 (서브쿼리 없음)

컴퓨터가 장부를 한 장씩 넘기며 그 줄에만 스티커를 붙여요.

  1. 첫 번째 7번 기록(1월)을 봄: "오늘 아니네? '대여 가능' 스티커!"
  2. 두 번째 7번 기록(5월)을 봄: "오늘 아니네? '대여 가능' 스티커!"
  3. 세 번째 7번 기록(10월)을 봄: "오! 오늘이네? '대여중' 스티커!"

자, 이제 DISTINCT 마법을 부려볼까요? DISTINCT는 [차번호 + 스티커 이름]이 똑같아야 합쳐줘요.

  • [7번, 대여 가능] (1, 2번 기록이 합쳐짐)
  • [7번, 대여중] (3번 기록은 글자가 달라서 안 합쳐짐)
  • 결과: 7번 차가 '대여 가능'이기도 하고 '대여중'이기도 한 이상한 결과가 나와요.

✅ 첫 번째 코드 (서브쿼리 있음)

이번엔 컴퓨터가 명단을 먼저 확인하고 대답해요.

  1. 서브쿼리: "오늘(10/16) 차 빌려 간 녀석 누구야?" → "7번이요!" (비밀 명단에 7번을 적어둠)
  2. 메인쿼리: 이제 장부의 7번 기록들을 보며 질문해요.
    • 1월 기록을 볼 때: "이거 7번이네? 아까 그 명단에 7번 있었지? 그럼 넌 '대여중'이야."
    • 5월 기록을 볼 때: "이것도 7번이네? 아까 명단에 있었지? 그럼 너도 '대여중'이야."
    • 10월 기록을 볼 때: "이것도 7번이네? 명단에 있지? 너도 '대여중'!"

자, 이제 DISTINCT 마법을 부려볼까요?

  • [7번, 대여중]
  • [7번, 대여중]
  • [7번, 대여중] 세 줄 다 똑같죠? 그래서 [7번, 대여중] 딱 한 줄로 깔끔하게 합쳐지는 거예요!

3. 최종 정리

  • 서브쿼리가 없으면: 기록 하나하나의 '과거 상태'와 '현재 상태'를 따로따로 판정해서 결과가 꼬인다.
  • 서브쿼리가 있으면: 이 차가 오늘 명단에 이름이 한 번이라도 올랐는지만 확인해서, 모든 기록을 현재 상태('대여중')로 통일시켜 버린다. 그래서 DISTINCT를 썼을 때 깔끔하게 한 줄이 된다!

Q60. 년, 월, 성별 별 상품 구매 회원 수 구하기

1. 문제 링크: https://school.programmers.co.kr/learn/courses/30/lessons/131532

2. 정답 코드:

SELECT
    SUBSTR(o.SALES_DATE, 1, 4) AS YEAR,
    SUBSTR(o.SALES_DATE, 6, 2) AS MONTH,
    u.GENDER,
    COUNT(DISTINCT u.USER_ID) AS USERS
FROM USER_INFO AS u
JOIN ONLINE_SALE AS o
  ON u.USER_ID = o.USER_ID
 AND u.GENDER IS NOT NULL
GROUP BY SUBSTR(o.SALES_DATE, 1, 4), SUBSTR(o.SALES_DATE, 6, 2), u.GENDER
ORDER BY SUBSTR(o.SALES_DATE, 1, 4), SUBSTR(o.SALES_DATE, 6, 2), u.GENDER

# AND 조건으로 GENDER가 NOT NULL인 행만 가져옴

3. 오류 상황: GENDER 값이 NULL인 행이 있음 → USERS 컬럼에 대해 제대로 COUNT가 되지 않음

4. 시도 방법: 문제에서 놓친 부분이 있는지 다시 읽어 봄

5. 최종 문제 해결 방법: GENDER IS NOT NULL 조건을 주고, DISTINCT도 넣음


라이브 세션) Python 기초 강의 4일차 - 문풀날 [조건문, 반복문]

조건문 문풀날 연습문제

필수예제 7번

사용자로부터 정수를 입력받은 뒤, 해당 정수가 다음 조건 중 하나에 해당하는지 판별하는 프로그램을 작성하세요.

  • 3의 배수이면서 동시에 7의 배수인 경우: "3과 7의 공배수입니다." 출력
  • 3의 배수이지만 7의 배수는 아닌 경우: "3의 배수입니다." 출력
  • 7의 배수이지만 3의 배수는 아닌 경우: "7의 배수입니다." 출력
  • 위의 어떤 조건도 만족하지 않으면: "3과 7의 배수가 아닙니다." 출력
테스트 입력값
입력: 21 21은 3의 배수이면서 7의 배수 → "3과 7의 공배수입니다."
입력: 9 9는 3의 배수지만 7의 배수 아님 → "3의 배수입니다."
입력: 14 14는 7의 배수지만 3의 배수 아님 → "7의 배수입니다."
입력: 10 3의 배수도, 7의 배수도 아님 → "3과 7의 배수가 아닙니다."
# 필수예제 7번

num = int(input("정수를 입력해주세요: "))

if num % 3 == 0 and num % 7 == 0 :
  print("3과 7의 공배수입니다.")
elif num % 3 == 0 :
  print("3의 배수입니다.")
elif num % 7 == 0 :
  print("7의 배수입니다.")
else :
  print("3과 7의 배수가 아닙니다.")

코드 실행 결과
다른 코드도 가능!

 

필수예제 8번

사용자로부터 문자열을 입력받아, 해당 문자열이 모두 알파벳으로만 이루어져 있으며(공백 없음), 길이가 8 이상인 경우 "사용 가능한 비밀번호입니다."를 출력하고, 그렇지 않으면 "사용 불가능한 비밀번호입니다."를 출력하세요.

특이 사항(아래 함수들을 모른다면 google 검색 or chatgpt 검색!!! ex. 파이썬 isalpha() 검색 후 정리된 블로그 글을 보고, 해당 문제에 적용!)

  1. isaplha() 사용(해당 문자열이 모두 알파벳으로만 이뤄져 있는지 확인하는 함수)
  2. len() 사용(문자열 길이 측정하는 함수)
테스트 입력값
입력: abcdefgh 전부 알파벳, 길이 8 → "사용 가능한 비밀번호입니다."
입력: abc123 숫자 포함 → "사용 불가능한 비밀번호입니다."
입력: abc 전부 알파벳이나 길이 3 < 8 → "사용 불가능한 비밀번호입니다."
# 필수예제 8번

text = input("사용하고자 하는 비밀번호를 입력하세요: ")

if text.isalpha() and len(text) == 8 :
  print("사용 가능한 비밀번호입니다.") 
else :
  print("사용 불가능한 비밀번호입니다.")

코드 실행 결과

ISALPHA()
: 문자열이 오직 알파벳(한글 포함)으로만 구성되어 있는지 확인
ex. text.isalpha()  ← 이런 식으로 원하는 변수.isalpha() 형태로 사용! (메서드라서)

반복문 문풀날 연습문제

 

필수예제 1번

문제 1부터 20까지의 숫자 중에서 👉 3의 배수이지만 6의 배수는 아닌 수만 출력하세요.

조건

  • range()를 반드시 사용하세요.
  • if 조건은 한 줄로 작성하세요.
for i in range(1, 21) :
  if i % 3 == 0 and i % 6 != 0 :
    print(i)

코드 실행 결과

 

필수예제 2번

문제 1부터 10까지 숫자를 출력하되, 👉 짝수는 건너뛰고, 👉 출력된 숫자의 개수를 마지막에 출력하세요.

for i in range(1, 11, 2) :
  print(i)

print(f"출력된 숫자 개수: {len(range(1, 11, 2))}")

코드 실행 결과

len(rarge(1, 11, 2)) 써봤는데, 한번에 실행되니까 신기했다..!

다른 코드도 가능!

count = 1

while count < 5:
    print(count)
    count += 1

코드 실행 결과

 

필수예제 4

문제 문자열을 입력받아, 👉 짝수 인덱스의 문자만 출력하세요.

text = input("문자열을 입력하세요: ")

for chr in text[0::2] :
  print(chr)

코드 실행 결과
enumerate() 사용
len() 사용

 

필수예제 5

문제 아래와 같은 출력이 나오도록 코드를 작성하세요.

조건

  • 반드시 중첩 for문을 사용하세요.
  • 바깥 반복문과 안쪽 반복문의 역할을 명확히 구분하세요.
for i in range(1, 3) :
  for j in range(1, 4) :
    print(i, j)

코드 실행 결과

 

필수예제 6

문제 사용자에게 숫자를 계속 입력받아 합을 누적하세요. 👉 단, 0을 입력하면 종료하고, 👉 0은 합계에 포함하지 마세요.

num = 0

while True :
  user = int(input("숫자 입력: "))

  if user == 0 :
    break
    
  num += user

print(f'총합: {num}')

코드 실행 결과

if랑 break 활용하는 방법 기억하기 + while 옆에 True나 1 적기!

break 안 쓰고도 동일 결과 나옴

 

필수예제 7

문제 사용자로부터 양의 정수 n을 입력받아, 1부터 n까지의 숫자를 차례대로 출력하는 프로그램을 작성하세요.

num = int(input('입력: '))

for i in range(1, num+1) :
  print(i)

코드 실행 결과

 

필수예제 8

문제 사용자로부터 정수 n을 입력받아, n부터 1까지 역순으로 출력하는 프로그램을 작성하세요.

num = int(input("입력: "))

for i in range(num, 0, -1) :
  print(i)

코드 실행 결과

range(num , 0, -1) : 역순으로 출력하는 명령 기억하기!

 

필수예제 9

문제 사용자로부터 양의 정수 n을 입력받아, 1부터 n까지의 합을 구하여 출력하는 프로그램을 작성하세요.

result = 0
num = int(input("입력: "))

for i in range(1, num+1) :
  result += i
print(f"1부터 {num}까지의 합은 {result}")

코드 실행 결과


미니 세션) AI를 활용한 효과적인 공부법

- AI 시대에는 아무도 해 보지 않은 질문 = 근원적 질문 을 하는 능력이 중요하다!

→ 이전에 누가 했던 질문은 AI가 이미 다 알고 있으니까

 

- NotebookLM : 사용자가 업로드한 문서, 노트, 링크 등을 기반으로 다양한 형태의 컨텐츠를 생성할 수 있는 도구

→ 할루시네이션을 최대한 줄여서 원하는 형태로 재구성 해줌!

 

- 생성형 AI의 방식 : 데이터 기반으로 가장 그럴듯한 단어를 예측하기 위한 통계 머신 → 확률 기반의 답변이기 때문에 할루시네이션이 생길 수 있다!

 

- AI가 내 정보를 기억한다? 아니다! → 새로운 채팅을 입력할 때 이전 대화들까지 모두 포함해서 정보를 찾기 때문에 기억하는 것처럼 보이는 것


데이터 분석 파이썬 종합반) 챕터 2 ~ 3

2-4. 튜플

튜플 (소괄호) or 괄호 없이 그냥 a, b, c, ... 해도 튜플

: 리스트랑 비슷하긴 한데, 한 번 생성되면 그 이후에는 바꿀 수 없음!

 

튜플의 메서드(Methods)

  • count() : 지정된 요소의 개수를 반환
  • index() : 지정된 요소의 인덱스를 반환
# 튜플 생성
my_tuple = (1, 2, 3, 4, 1, 2, 3)

# count() 메서드 예제
count_of_1 = my_tuple.count(1)
print("Count of 1:", count_of_1)  # 출력: 2

# index() 메서드 예제
index_of_3 = my_tuple.index(3)
print("Index of 3:", index_of_3)  # 출력: 2

 

튜플 ↔ 리스트 변경 방법

# 튜플을 리스트로 변경하기
my_tuple = (1, 2, 3, 4, 5)
my_list = list(my_tuple)
print(my_list)  # 출력: [1, 2, 3, 4, 5]

# 리스트를 튜플로 변경하기
my_list = [1, 2, 3, 4, 5]
my_tuple = tuple(my_list)
print(my_tuple)  # 출력: (1, 2, 3, 4, 5)

2-5. 딕셔너리

딕셔너리 {중괄호}

: 키 - 값 이렇게 쌍으로 이뤄진 구조 (키는 중복 X, 고유값이어야 함)

my_dict = {
    'key1': 'value1',
    'key2': 'value2',
    'key3': 'value3'
}

예시)

# 빈 딕셔너리 생성
empty_dict = {}

# 학생 성적표
grades = {
    'Alice': 90,
    'Bob': 85,
    'Charlie': 88
}

# 접근하기
print(grades['Alice'])  # 출력: 90

# 값 수정하기
grades['Bob'] = 95

# 요소 추가하기
grades['David'] = 78

# 요소 삭제하기
del grades['Charlie']

 

딕셔너리의 메서드(Methods)

  • keys(): 모든 키를 dict_keys 객체로 반환
  • values(): 모든 값을 dict_values 객체로 반환
  • items(): 모든 키-값 쌍을 (키, 값) 튜플로 구성된 dict_items 객체로 반환
  • get(): 지정된 키에 대한 값을 반환합니다. 키가 존재하지 않으면 기본값을 반환
  • pop(): 지정된 키와 해당 값을 딕셔너리에서 제거하고 값을 반환
  • popitem(): 딕셔너리에서 마지막 키-값 쌍을 제거하고 반환
# 딕셔너리 생성
my_dict = {'name': 'John', 'age': 30, 'city': 'New York'}

# keys() 메서드 예제
keys = my_dict.keys()
print("Keys:", keys)  # 출력: dict_keys(['name', 'age', 'city'])

# values() 메서드 예제
values = my_dict.values()
print("Values:", values)  # 출력: dict_values(['John', 30, 'New York'])

# items() 메서드 예제
items = my_dict.items()
print("Items:", items)  # 출력: dict_items([('name', 'John'), ('age', 30), ('city', 'New York')])

# get() 메서드 예제
age = my_dict.get('age')
print("Age:", age)  # 출력: 30

# pop() 메서드 예제
city = my_dict.pop('city')
print("City:", city)  # 출력: New York
print("Dictionary after pop:", my_dict)  # 출력: {'name': 'John', 'age': 30}

# popitem() 메서드 예제
last_item = my_dict.popitem()
print("Last item popped:", last_item)  # 출력: ('age', 30)
print("Dictionary after popitem:", my_dict)  # 출력: {'name': 'John'}

오늘은 오후 내내 세션을 듣느라 개인 공부를 거의 하지 못했다. AI 강의에서는 타 수강생분들의 깊이 있는 질문과 튜터님의 자세한 설명 덕분에, 다양한 AI 툴과 AI 활용 시 유의해야 할 점들을 알 수 있어 특히 유익했다.

또한 GitHub 사용법을 학습했는데, 생각보다 시간이 많이 소요됐다. 마지막에 팀원들과 튜터님께 따로 질문을 드리며 막혔던 부분들을 하나씩 해결했고, 이제서야 GitHub를 어떻게 활용해야 할지 감이 잡힌 상태다.

내일은 리스트/튜플/딕셔너리처럼 어렵고 중요한 내용을 라이브 세션에서 다룰 예정이라, 아침부터 집중해서 잘 따라가야 할 것 같다. 내일만 지나면 주말이니, 조금 더 힘내서 마무리해야겠다!
공지사항
최근에 올라온 글
최근에 달린 댓글
Total
Today
Yesterday
링크
«   2026/05   »
1 2
3 4 5 6 7 8 9
10 11 12 13 14 15 16
17 18 19 20 21 22 23
24 25 26 27 28 29 30
31
글 보관함