Notice
Recent Posts
Recent Comments
Link
«   2024/11   »
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
Tags
more
Archives
Today
Total
관리 메뉴

Nonamed Develog

[TIL] AI 웹 개발 7기 사전 캠프 3-2 본문

WHAT I LEARN/TIL

[TIL] AI 웹 개발 7기 사전 캠프 3-2

노네임드개발자 2024. 6. 4. 19:04

일일 알고리즘 코드카타 풀어보기

제한 조건

x는 -10000000 이상, 10000000 이하인 정수입니다.

n은 1000 이하인 자연수입니다.

def solution(x, n):
    answer = []
    for i in range(x,(n+1)*x,x):
        answer.append(i)
    return answer

for문의 range(start,stop,step) 함수를 이용하여 해당하는 수를 answer에 리스트 되게 해봤다. 예시 코드는 모두 맞았지만, 정답 제출시 오류가 또 일어났다.

0을 넣으면 [0]이 나오게 예시 코드를 넣었고 ValueError: range() arg 3 must not be zero 라는 오류가 발생했다. 알아보니 range()의 3번 째 인자는 0이 될 수 없다고 한다.

def solution(x, n):
    answer = []
    if x == 0:
        answer.append(0)
    else:
        for i in range(x,(n+1)*x,x):
            answer.append(i)
    return answer

0을 해결하고자 if문으로 x==0일 때 [0]이 나오게 하고 나머지는 똑같이 진행해봤지만 에러는 여전했다.

def solution(x, n):
    if x == 0:
        answer = [0]
    else:
        answer = list(range(x, (n+1)*x, x))
    return answer

리스트를 잘못 짤 수도 있다는 생각이 들어서 조금 더 간단하게 하여 실행했지만 오류는 여전했다.

def solution(x, n):
    if x == 0:
        answer = [0] * n
    else:
        answer = list(range(x, (n+1)*x, x))
    return answer

매니져님께 여쭤보니 조건문에서 문제가 있음을 알려주셨다. x==0 일 때 n(갯수)는 무의미하다고 문제를 이해했는데, 예를 들어 n이 3일 경우 [0, 0, 0]라는 리스트가 만들어져야 했다. 그래서 n만큼 나오도록 조건문에 n을 곱해주니 답이 되었다.

예외는 항상 문제 속에 있다. 막혔을 때는 문제를 다시 한번 확인해보자.

 

엑셀보다 쉽고 빠른 SQL 3주차

3-1 3주차 오늘 배울 것

 

이번 수업에서 배울 내용 맛보기

  • 문자 데이터는 있는 그대로만 사용 가능한걸까?
  • 배달 시간 구간에 따라서 수수료를 계산하고 싶은데, 시간을 조건으로 줄 수는 없는걸까?
  • 수업에서 배운대로 Query 를 썼는데 왜 오류가 나는걸까?

3-2 업무 필요한 문자 포맷이 다를 때, SQL로 가공하기 (REPLACE, SUBSTRING, CONCAT)

1) Query 결과를 바로 사용할 수 없는 경우

  • 데이터를 보니 잘못된 값이 있어요. 이전에 사용하던 값이어서 다른 문자로 수정을 해줘야하는데, 하나하나 수동으로 하기는 너무 많아서 SQL 로 바꿀 수 있을까요?
  • 저는 주소 전체가 아닌 ‘시도’ 정보만 필요해요. 서울의 통계만 구하고 싶은데, 전체 주소가 아닌 ‘서울’ 로 문자를 변경할 수는 없을까요?
  • 저는 보고서를 작성할 때 사업장 명과 함께 지역이 같이 나와야해요. ‘사업장 [지역]’ 과 같은 형태로 문자 포맷을 변경할 수 있을까요?

2) 특정 문자를 다른 문자로 바꾸기 (실습 포함)

  • 함수명 : replace
  • 사용 방법 : replace(바꿀 컬럼, 현재 값, 바꿀 값)

select restaurant_name "원래 상점명",

replace(restaurant_name, 'Blue', 'Pink') "바뀐 상점명" 식당 이름 중 Blue인 것을 Pink로 바꾸는 

from food_orders

where restaurant_name like '%Blue Ribbon%'

  • 예시1) 최근에 상점 이름이 바뀌었지만 과거 데이터에는 옛날 이름으로 저장되어있어요
  • 예시2) 예전에 ‘문곡리’ 라는 지명이 ‘문가리’ 로 바뀌었어요

SELECT addr,

REPLACE(addr'문곡리''문가리'"바뀐 주소"

FROM food_orders

WHERE addr LIKE '%문곡리%'

 

3) 원하는 문자만 남기기 (실습 포함)

  • SQL 에서는 특정 문자만 골라서 조회할 수 있는 기능을 제공합니다
  • 예시) 전체 주소에서 앞부분인 ‘시도’ 부분만 필요해요
  • 함수명 : substring (substr)
  • 사용 방법 : substr(조회 할 컬럼, 시작 위치, 글자 수)

select addr "원래 주소",

substr(addr, 1, 2) "시도" #1: 첫번째 문자부터 뽑는 것(5: 다섯번째 문자) 2: 글자수 즉 첫번 째 문자부터 2글자 뽑는 것

공백도 카운트에 포함 됨.

from food_orders

where addr like '%서울특별시%'

 

4) 여러 컬럼의 문자를 합치기 (실습 포함)

  • SQL 에서는 여러 컬럼의 값을 하나로 합칠 수 있는 기능을 제공합니다.
  • 예시) 서울시에 있는 음식점은 ‘[서울] 음식점명’ 이라고 수정하고 싶어요
  • 함수명 : concat
  • 사용 방법 : concat(붙이고 싶은 값1, 붙이고 싶은 값2, 붙이고 싶은 값3, .....)

select restaurant_name "원래 이름",

addr "원래 주소",

concat(restaurant_name, '-', cuisine_type) "음식타입별 음식점",

concat('[', substring(addr, 1, 2), '] ', restaurant_name) "바뀐 이름"

from food_orders

where addr like '%서울%'

 

3-3 [실습] 문자 데이터를 바꾸고, GROUP BY 사용하기

1) [실습] 서울 지역의 음식 타입별 평균 음식 주문금액 구하기 (출력 : ‘서울’, ‘타입’, ‘평균 금액’)

1. Query 를 적기 전에 흐름을 정리해보기

2. 구문으로 만들기

3. 전체 구조로 합치기

SELECT SUBSTR(addr, 1, 2) "지역",

cuisine_type,

AVG(price) "평균 금액"

FROM food_orders

WHERE addr LIKE '%서울%'

group by 1, # SUBSTR(addr12), cuisine_type 이라고 적어도 된다,

 

2) [실습] 이메일 도메인별 고객 수와 평균 연령 구하기(이메일 도메인, 고객 수, 평균 연령)

1. Query 를 적기 전에 흐름을 정리해보기 

2. 구문으로 만들기

3. 전체 구조로 합치기

SELECT SUBSTR(email, 10) "도메인", #substr에서 글자의 수를 특정하지 않으면 끝까지 나온다.

count(1) "고객 수", # 모든 데이터 값을 불러온다(1)

avg(age) "평균 연령"

FROM customers

group by 1

 

3) [실습] ‘[지역(시도)] 음식점이름 (음식종류)’ 컬럼을 만들고, 총 주문건수 구하기

1. Query 를 적기 전에 흐름을 정리해보기

2. 구문으로 만들기

3. 전체 구조로 합치기

SELECT CONCAT('[',SUBSTR(addr, 1, 2), ']', restaurant_name, ' (', cuisine_type, ')') "음식점",

count(1) "주문 건수"

FROM food_orders

group by 1

 

3-4 조건에 따라 포맷을 다르게 변경해야한다면 (IF, CASE)

1) Group by 처럼 조건도 카테고리별로 줄 수 있을까?

2) 조건에 따라 다른 방법을 적용하고 싶을 때 - If 문 기초 (실습 포함)

  • IF 문은 원하는 조건에 충족할 때 적용할 방법과 아닌 방법을 지정해 줄 수 있습니다
  • 예시) 음식 타입을 ‘Korean’ 일 때는 ‘한식’, ‘Korean’ 이 아닌 경우에는 ‘기타’ 라고 지정하고 싶어요
  • 함수명 : if
  • 사용 방법 : if(조건, 조건을 충족할 때, 조건을 충족하지 못할 때)

select restaurant_name,

cuisine_type "원래 음식 타입",

if(cuisine_type='Korean', '한식', '기타') "음식 타입"  #만약에 cuisine type korena이면 한식으로 하고 아니면 기타 

from food_orders

 

select addr "원래 주소",

if(addr like '%평택군%', replace(addr, '문곡리', '문가리'), addr) "바뀐 주소" 

#만약 주소가 평택군을 포함할 때 replace를 이용하여 문곡리를 문가리로 바꾸고 아니면 그냥 addr로 출력

from food_orders

where addr like '%문곡리%'

 

앞서 이메일 도메인을 출력하는 예제에서 gail은 @이 없었다. 그 것을 수정해보자!

select substring(if(email like '%gmail%', replace(email, 'gmail', '@gmail'), email), 10) "이메일 도메인"

#substr안에 if문을 결합한 경우 

count(customer_id) "고객 수",

avg(age) "평균 연령"

from customers

group by 1

 

3) 조건을 여러가지 지정하고 싶을 때 - Case 문 기초 (실습 포함)

  • Case 문은 각 조건별로 적용 할 값을 지정해 줄 수 있습니다.
  • 조건별로 지정을 해주기 때문에 아래와 같이 if 문을 여러번 쓴 효과를 낼 수 있습니다. if(조건1, 값1, if(조건2, 값2, 값3))
  • 예시) 음식 타입을 ‘Korean’ 일 때는 ‘한식’, ‘Japanese’ 혹은 ‘Chienese’ 일 때는 ‘아시아’, 그 외에는 ‘기타’ 라고 지정

 

SELECT CASE when cuisine_type = 'Korean' then '한식'

when cuisine_type in ('Japanese', 'Chinese') then '아시아'

else '기타' end "음식타입",

cuisine_type

FROM food_orders

  • 함수명 : case
  • 사용 방법 : case when 조건1 then 값(수식)1
                               when 조건2 then 값(수식)2
                               else 값(수식)3
                      end

select order_id,

price,

quantity,

case when quantity=1 then price

when quantity>=2 then price/quantity end "음식 단가" 예외가 없는 경우는 else는 생략 가

from food_orders

 

4) 조건을 사용할 수 있는 경우 알아보기

  • 새로운 카테고리 만들기
  • 연산식을 적용할 조건 지정하기
  • 다른 문법 안에서 적용하기

select restaurant_name,

addr,

case when addr like '%경기도%' then '경기도'

when addr like '%특별%' or addr like '%광역%' then substring(addr, 1, 5)

else substring(addr, 1, 2) end "변경된 주소"

from food_orders

 

3-5 [실습] SQL로 간단한 User Segmentation 해보기

1) [실습] 10세 이상, 30세 미만의 고객의 나이와 성별로 그룹 나누기 (이름도 같이 출력)

1. Query 를 적기 전에 흐름을 정리해보기

2. 구문으로 만들기

3. 전체 구조로 합치기

SELECT CASE when (age between 10 and 19) and gender='male' then '10대 남성'

when (age between 10 and 19) and gender='female' then '10대 남성'

when (age between 20 and 29) and gender='male' then '20대 남성'

when (age between 20 and 29) and gender='female' then '20대 여성' end "고객 분류",

name,

age,

gender

FROM customers

WHERE age BETWEEN 10 and 29

 

2) [실습] 음식 단가, 음식 종류 별로 음식점 그룹 나누기

(Korean = 한식 Japanese, Chinese, Thai, Vietnamese, Indian = 아시아식 그외 = 기타)

(가격 = 5000, 15000, 그 이상)

1. Query 를 적기 전에 흐름을 정리해보기

2. 구문으로 만들기

3. 전체 구조로 합치기

 

3-6 [실습] 조건문으로 서로 다른 식을 적용한 수수료 구해보기

1)[실습] 지역과 배달시간을 기반으로 배달수수료 구하기 (식당 이름, 주문 번호 함께 출력)

(지역 : 서울, 기타 - 서울일 때는 수수료 계산 * 1.1, 기타일 때는 곱하는 값 없음 시간 : 25분, 30분 - 25분 초과하면 음식 가격의 5%, 30분 초과하면 음식 가격의 10%)

1. Query 를 적기 전에 흐름을 정리해보기

2. 구문으로 만들기

3. 전체 구조로 합치기

SELECT CASE when delivery_time > 30 then price * 0.1 * if(addr like '%서울%', 1.1, 1) #배달시간이 30분 초과면. 음식가격에 0.1을 곱해야하는데 주소가 서울일 때는 1.1을 곱해주고 아닐 때는 1을 곱해준다.

when delivery_time between 26 and 29 then price * 0.05 * if(addr like '%서울%', 1.1, 1) #이미 앞의 case에서 조건을 충족했기 때문에 > 25로 대치 가능

else 0 end "수수료",

restaurant_name,

order_id,

price,

delivery_time,

addr

FROM food_orders

 

2) [실습] 주문 시기와 음식 수를 기반으로 배달할증료 구하기

(주문 시기 : 평일 기본료 = 3000 / 주말 기본료 = 3500 음식 수 : 3개 이하이면 할증 없음 / 3개 초과이면 기본료 * 1.2)

1. Query 를 적기 전에 흐름을 정리해보기

2. 구문으로 만들기

3. 전체 구조로 합치기

SELECT CASE when day_of_the_week = 'weekday' then 3000 * if(quantity > 3, 1.2, 1)

when day_of_the_week = 'weekend' then 3500 * if(quantity > 3, 1.2, 1)

end "배달할증료",

restaurant_name,

order_id,

day_of_the_week,

quantity

FROM food_orders

3-7 SQL문에 문제가 없는 것 같은데 왜 오류가 나나요_ (Data Type 오류 해결하기)

문자/숫자 계산을 했더니 오류가 났어요

data type: 데이터베이스는 문자와 숫자를 명확하게 나눈다. 보기에 숫자여도 문자일 수 있다.

abc vs 123: dbeaver에는 컬럼 옆에 문자인지 숫자인지 힌트가 나와있다.

 

cast 함수를 이용하여 해결 가능 

--숫자로 변경
cast(if(rating='Not given', '1', rating) as decimal) 
--문자로 변경
concat(restaurant_name, '-', cast(order_id as char))

 

HW. 3주차 숙제 해설

다음의 조건으로 배달시간이 늦었는지 판단하는 값을 만들어주세요. - 주중 : 25분 이상 - 주말 : 30분 이상

  1. SQL 문의 기본 구조로 시작
  2. 조건을 여러번 적용할 때 if, case 문 중 어떤 것을 이용할지 결정
  3. 조건에 ‘주중, 주말’ 조건과 ‘배달시간’ 조건을 동시에 줄 때 사용 할 논리연산자 결정

SELECT order_id,

restaurant_name,

day_of_the_week,

delivery_time,

CASE when delivery_time >= 25 and day_of_the_week = 'weekday' then 'Late'

when delivery_time >= 25 and day_of_the_week = 'weekend' then 'Late'

else 'On-time' end "지연여부"

FROM food_orders