기타/Python

250527_파이썬(if, for, while) , SQL(rank)

baektree 2025. 5. 27. 21:17

확실히 파이썬이 SQL보다 어렵게 느껴진다.

반복만이 살 길이다.. 가즈아!

 


1. 오늘 학습 한 내용을 나만의 언어로 정리하기

  • 조건문 if , elif , else
    • 조건이 참인 경우에만 특정 코드 블록을 실행
    • if 조건 충족할 때 elif if는 아니지만 elif 충족할 때 else 모두 아닐 때
    • 들여쓰기(indent) 및 띄어쓰기가 매우 중요 ⭐
    if 조건:
        # 조건이 참일 때 실행될 코드
    elif 다른조건:
        # 다른 조건이 참일 때 실행될 코드
    else:
        # 위의 조건이 모두 거짓일 때 실행될 코드
    
    • 비교연산(값을 계산)자
      • == : 같음
      • != : 같지 않음
    • 논리연산(값을 계산)자
      • not : 조건을 부정
    • 예시
    if x > 5:
        print("x는 5보다 큽니다.")
        if x < 15:
            print("x는 15보다 작습니다.")
        else:
            print("x는 15보다 큽니다.")
    else:
        print("x는 5보다 작거나 같습니다.")
    
  • 반복문 for
    • 반복가능한(iterable) 데이터를 변수에 넣기
    • 각 반복마다 값을 하나씩 가짐
    • 예시) fruits 요소를 fruit 변수에 하나씩 담기
    fruits = ["apple", "banana", "cherry"]
    for fruit in fruits:
        print(fruit)
        
    #결과
    apple
    banana
    cherry
    
    • 예시2) 문자열 순회하기
    for letter in "pencil":
        print(letter)
      
    #결과
    p
    e
    n
    c
    i
    l
    
    • range() 함수와 함께 사용하기
      • range()함수란?
      • 연속된 정수를 생성하는데 사용되는 내장 함수
      • 시작값, 끝값, 증가값을 인자로 받아 사용된다.
      • for 루프와 함께 자주 사용된다.
    for i in range(6):
    		print(i)
    
    #0부터 6바로 전까지 정수 시퀀스를 생성한다.
    0
    1
    2
    3
    4
    5
    
    for i in range(2, 7):
        print(i, end=' ')
    
    #2부터 시작하여 7바로 전까지 정수 시퀀스를 생성한다.
    # end=' ' 는 줄바꿈 없이 한칸 띄고 이어 생성
    
    2 3 4 5 6
    
    
    for i in range(1, 10, 2):
        print(i, end=' ')
        
    # 1부터 시작하여 10바로 전까지 정수 시퀀스를 생성한다.
    # 2씩 증가하여 생성한다.
    # end='' 는 줄바꿈 없이 한칸 띄고 이어 생성 
    
    1  3  5  7  9 
    
    
    • 별(*)로 삼각형 만들기
    • size = 5 for i in range(size): for j in range(i+1): print("*", end="") print() #풀이 1) i = 0, 1, 2, 3, 4 가 순서대로 들어감 2) i = 0일 때, j에는 0이 들어감 3) 이는 한번만 반복된다는 소리 4) 그래서 print("*), end="")한번만 실행 5) 결과 * 6) i = 1일 때, j에는 0, 1이 들어감 7) 이는 두번 반복된다는 소리 8) 따라서 print("*), end="")두번 실행 9) 결과 **
    • 별(*)로 역삼각형 만들기
    • size = 5 for i in range(size, 0, -1): for j in range(i): print("*", end="") print() #풀이 1) for i in range(size, 0, -1): 5부터 시작해서 0직전까지 -1씩 줄어가기 5 4 3 2 1 (cf -1이어서 감소하느 방향으로 감) 2) i=5이면 0,1,2,3,4가 j에 들어감 (5번) i=4이면 0,1,2,3이 j에 들어감 (4번) i=3이면 0,1,2가 j에 들어감 (3번) i=2이면 0,1이 j에 들어감 (2번) i=1이면 0이 j에 들어감 (1번) 3) 결과 ***** **** *** ** * tip j는 실제로 출력에 사용되는 게 아니라 몇 번 반복할지만 결정하는 용도이다.
  • 반복문 while
    • 조건을 만족하는 동안 코드 블록을 반복적으로 실행
    • 특정 조건이 True로 평가될 때까지 코드 블록이 반복적으로 실행
    i = 1
    while i <= 5:
        print(i)
        i += 1
        
    #답
    1
    2
    3
    4
    5
    
    #풀이 
    1) i = 1 일 때, print(1) = 1 
    2) i에 1을 증가시키기
    ...
    3) i = 5 일 때, print(5) = 5
    4) 5에 1을 추가하면 6이라 더이상 while이 돌지 않음.
    
    • 특정 조건에 따라 반복 동작을 제어할 제어문pass - ex 그냥 지나가기
      numbers = [1, 2, 3, 4, 5]
      for num in numbers:
          if num % 2 == 0:
              pass
          else:
              print(num, "은 홀수입니다.")
              
      #풀이 
      짝수 일 경우 그냥 지나가서 else print(num, "은 홀수입니다.")출력
      
      num = 0
      while num < 10:
          num += 1
          if num % 2 == 1:
              continue
          print(num)
          
      #풀이
      num이 10보다 작으면 1씩 추가 
      그러고 그것이 홀수이면 다시 while로 계속
      짝수이면 아래 코드블록인 num 실행
      
      #답
      2
      4
      6
      8
      10
      
      • 팩토리얼
      num = 5
      factorial = 1
      while num > 0:
          factorial *= num
          num -= 1
      print("Factorial of 5 is:", factorial)
      
      1) num이 5이고, factorial이 1이면 
      2) factorial = factorial * num 이니까 
         facctorial은 5로 반환
         num은 한개씩 줄여서 4 
      즉 num이 5  --> 1 x 5 
      3) num이 4  --> 1 x 5 x 4 
      4) num이 3  --> 1 x 5 x 4 X 3 
      5) num이 2  --> 1 x 5 x 4 x 3 x 2
      6) num이 1  --> 1 x 5 x 4 x 3 x 2 x 1 
      7) while 이 끝나고 마지막 factorial은 120  
      
    • continue - ex 반복문으로 돌아가기
    • break - ex 사용자가 ‘quit’를 입력할 때 반복문 종료

2. 학습하며 겪었던 문제점 & 에러

  • 문제1) SQL 코드타카 문제(FLOOR 함수 - 소수점 이하 버리기)
    • 내가 겪은 문제점?
      • SQL 코드타카 44번 문제
    • 내가 했던 풀이 방식, 왜 틀렸는지?
      • 풀이방식은 맞았는데 더 쉽고, 효과적인 방식이 있는 것 같아서 가져와 봤다.
      • 문제관건은 10000원 기준으로 가격 정렬
        • 내가 푼 풀이 방식
          • CASE WHEN 함수를 이용해 만원대 별로 이름 매김
          • BUT 만원대부터 몇십만원대까지 있으면 쿼리가 굉장히 길어지는 번거로움이 생김
          • SELECT CASE WHEN PRICE < 10000 THEN 0 WHEN PRICE < 20000 THEN 10000 WHEN PRICE < 30000 THEN 20000 WHEN PRICE < 40000 THEN 30000 WHEN PRICE < 50000 THEN 40000 WHEN PRICE < 60000 THEN 50000 WHEN PRICE < 70000 THEN 60000 WHEN PRICE < 80000 THEN 70000 WHEN PRICE < 90000 THEN 80000 END AS PRICE_GROUP, COUNT(*) AS PRODUCTS FROM PRODUCT GROUP BY 1 ORDER BY 1
        • 다른 사람이 한 풀이 방식
          • FLOOR 함수 사용
            • 어떤 수보다 작거나 같은 최대 정수를 반환함
            • 즉 소수점 이하를 무조건 버림
              • EX FLOOR(3.7) → 3
              • EX FLOOR(-3.7) → -4 (※ 단순히 소수점 버리는 게 아니라 아래 방향으로 내림)
          • 풀이설명
            1. 만약 150000원이라면?
              1. 15000/10000 = 1. 5
              2. FLOOR(15000/10000) = 1
              3. 여기에 다시 * 10000하면 만원 별 구간대 설정 1*10000 = 10000
            2. 만약 7000원이라면?
              1. 7000/10000 = 0.7
              2. FLOOR(0.7) = 0
              3. 여기에 다시 *10000이면 0이 나옴
          SELECT FLOOR(PRICE/10000) * 10000 AS PRICE_GROUP,
          				COUNT(*) AS PRODUCTS
          FROM PRODUCT
          GROUP BY PRICE_GROUP 
          ORDER BY PRICE_GROUP
          
      • → EX 10000원대, 20000원대, 30000원대
      • https://school.programmers.co.kr/learn/courses/30/lessons/131530
    • 앞으로 어떻게 하면 좋을지?
      • 만원대별로 구간 나누는 거면!
        • 만원으로 나눈다.
        • FLOOR함수를 활용해 소수점 이하는 버린다.
        • 다시 만원을 곱한다!
        • 끝!
  • 문제2) SQL 코드타카 48번문제 (rank () over ~)
    • 문제
      • REST_INFO 테이블에서 음식종류별로 즐겨찾기수가 가장 많은 식당의 음식 종류, ID, 식당 이름, 즐겨찾기수를 조회하는 SQL문을 작성해주세요. 이때 결과는 음식 종류를 기준으로 내림차순 정렬해주세요.
    • 어려운 부분
      • window 함수 rank 인 것 같은데 정확한 문법, 구문이 생각나지 않는다.
      • window 함수를 다시 떠올려보자!
        • 정의: 윈도우 함수는 각 행의 관계를 정의하기 위한 함수로 그룹 내의 연산을 쉽게 만들어 준다.
        • 예시: 1️⃣ 한식 식당 중에서 주문건수가 많은 순으로 순위를 매기자면? 2️⃣ 한식 식당 전체 주문건수 중에서 A식당이 차지하는 비율을 알고 싶은데
        window_function(argument) over (partition by 그룹 기준 컬럼 order by 정렬 기준)
        
        
        • window_function : 기능 명을 사용해줍니다. (sum, avg 와 같이 기능명이 있습니다)
        • argument : 함수에 따라 작성하거나 생략합니다.
        • partition by : 그룹을 나누기 위한 기준입니다. group by 절과 유사하다고 생각해주시면 됩니다.
        • order by : window function 을 적용할 때 정렬 할 컬럼 기준을 적어줍니다.
        • 예시1
          1. 음식타입, 레스토랑, 주문건수를 조회한다. (단 음식타입, 레스토랑 별 주문건수를 조회한다. )
          2. 그것을 서브쿼리로 묶어 테이블로 만들고
          3. 거기서 음식 타입, 레스토랑, 랭킹, 주문건수를 조회한다.
          4. rank는 rank () over (partition by 음식타입 ordrer by 주문건수 desc) 이다.
        • 음식 타입별로 주문건수가 가장 많은 상점 3개씩 조회하기 SELECT cuisine_type, restaurant_name, rank () over (partition by cuisine_type order by order_count desc) rn, order_count from ( select cuisine_type, restaurant_name, count(*) as order_count from food_orders group by 1, 2 ) a
      • 떠올린 것을 토대로 다시 풀어보자
        • 정답풀이1 (나)
          1. 음식 종류, 아이디, 음식점명, 즐겨찾기 수, 랭킹을 구한다.
          2. RANK () OVER (PARTITION BY FOOD_TYPE ODRDER BY FAVORITE DESC) AS FAVORITE 음식종류별 순위를 구하는데 기준은 즐겨찾기 내림차순이야
          3. 서브쿼리로 묶어서 테이블로 만든다.
          4. 여기서 랭킹이 1인 것만 조회한다.
          5. 음식 종류 내림차순 정렬 한다.
          SELECT FOOD_TYPE,
                  REST_ID,
                  REST_NAME,
                  FAVORITES
          FROM
          (
          SELECT FOOD_TYPE,
                  REST_ID,
                  REST_NAME,
                  FAVORITES,
                  RANK() OVER (PARTITION BY FOOD_TYPE ORDER BY FAVORITES DESC) RANKING
          FROM REST_INFO
          ) a
          WHERE RANKING = 1
          ORDER BY FOOD_TYPE DESC
          
        • 정답풀이2 (다른 사람)
        • https://school.programmers.co.kr/questions/88059