자기계발 Diary

오늘의 공부 Day_12(SQL공부,Python공부)

siron94 2024. 11. 22. 19:45

SQL

 

 

업무 시작을 단축시켜 주는 마법의 문법 (Window Function - RANK, SUM)

  • 기본 SQL 구조로 해결하기 위해서는 복잡하게 Subquery 문을 이용하거나, 여러 번의 연산을 수행해줘야 하지만, 자체적으로 제공해 주는 기능을 이용하면 조금 더 편리합니다.
  • 중요한 것은 윈도우 함수는 해당 행만이 아니라, 그 행을 묶은 단위로 해당 함수를 적용한다는 것입니다
.
기본구조
window_function(argument) over (partition by 그룹 기준 컬럼 order by 정렬 기준)
  • window_function : 기능 명을 사용해줍니다. (sum, avg 와 같이 기능명이 있습니다)
  • argument : 함수에 따라 작성하거나 생략합니다.
  • partition by : 그룹을 나누기 위한 기준입니다. group by 절과 유사하다고 생각해주시면 됩니다.
  • order by : window function 을 적용할 때 정렬 할 컬럼 기준을 적어줍니다.

 

 

RANK(N 번째까지의 대상을 조회하고 싶을 때)

  • Rank는 이름에서 유추할 수 있듯이 ‘특정 기준으로 순위를 매겨주는기능입니다.
  • 예를 들어, 주문 건수별 순위 매기기, 결제 시간이 빠른 순으로 순위 매기기 등이 가능합니다.
     
  • RANK 함수는 괄호 안에 아무 값도 적지 않고, ORDER BY를 사용하여 순위를 매깁니다.
  • 경우에 따라 ORDER BY를 생략하는 케이스도 있습니다.
  • OVER 후 PARTITION BY와 ORDER BY를 작성해 단위별로 데이터를 묶기 

[실습] 음식 타입별로 주문 건수가 가장 많은 상점 3개씩 조회하고, 음식 타입별, 순위별 정렬하기

select cuisine_type,
           restaurant_name,
           order_count,
           rn "순위"
from
(
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(1) order_count
from food_orders
group by 1, 2
) a
) b
where rn<=3
order by 1, 4

 

 

 

Sum(전체에서 차지하는 비율, 누적합을 구할 때)

  • Sum 은 앞서 배운 합계를 구하는 기능과 동일합니다.
  • 어떤 행을 단위로 묶어 순위 또는 누적을 구할 수 있도록 도와주는 함수입니다.
  • 다만, 누적합이 필요하거나 카테고리별 합계컬럼와 원본 컬럼을 함께 이용할 때 유용하게 사용할 수 있습니다.
  • 누적 함수로 'SUM'을 사용하면서 'PARTITION BY cuisine_type'으로 덩어리를 지정하고, 'ORDER BY cnt_order'로 정렬하면서 순차적으로 내려와 누적을 구합니다.

 

[실습] 각 음식점의 주문 건이주문 건이 해당 음식 타입에서 차지하는 비율을 구하고, 주문 건이 낮은 순으로 정렬했을 때 누적 합 구하기

select cuisine_type,
           restaurant_name,
           cnt_order,
           sum(cnt_order) over (partition by cuisine_type) sum_cuisine,
           sum(cnt_order) over (partition by cuisine_type order by cnt_order) cum_cuisine
from
(
select cuisine_type, 
restaurant_name, 
count(1) cnt_order
from food_orders
group by 1, 2
) a
order by cuisine_type , cnt_order , cum_cuisine

 

 

 

날짜 포맷과 조건까지 SQL로 한 번에 끝내기 (포맷 함수)

  • 데이터에 날짜를 지정하거나 조건에 날짜를 사용할 수 있습니다.
  • 문자타입, 숫자타입과 같이 날짜 데이터도 특정한 타입을 가지고 있습니다.
  • 년, 월, 일, 시, 분, 초 등의 값을 모두 갖고 있으며 목적에 따라 ‘월’, ‘주’, ‘일’ 등으로 포맷을 변경할 수도 있습니다.

 

 

[실습] 3월 조건으로 지정하고, 연도별로 정렬하기

select date_format(date(date), '%Y') "년",
          date_format(date(date), '%m') "월",
          date_format(date(data), 'Y%m') "년월",
          count(1) "주문건수"
from food_orders a inner join payments b on a.order_id=b.order_id
where date_format(date(date), '%m')='03'
group by 1, 2
order by 1

 

 

 


Python

 

변수 선언과 자료형

 

  • 변수 선언
    • 파이썬에서 새 변수를 만들 때는 변수이름 = 값의 형태로 써요. a = b와 b = a는 다르다는 사실! 출력할 때는 위에서 본 것처럼 print()를 씁니다
a = 3        # 3을 a에 넣는다.
print(a)
b = a        # a에 들어 있는 값인 3을 b에 넣는다.
print(b)
a = 5        # a에 5라는 새로운 값을 넣는다.
print(a, b)  # 5 3

 

 

숫자형 자료형

  • 자료형이란 프로그래밍을 할 때 쓰이는 숫자, 문자열 등 자료 형태로 사용하는 모든 것을 뜻합니다.

 

  • 다양한 형태의 숫자를 쓸 수 있습니다.
a = 5
b = 4.8

 

  • 숫자 간에는 사칙연산이 가능합니다. 몫과 나머지도 구할 수 있어요.
a = 7
b = 2

a+b   # 9 
a-b   # 5
a*b   # 14
a/b   # 3.5

a+3*b         # 13 (여러 연산을 한 줄에 할 경우 사칙연산의 순서대로!)
(a+3)*b       # 20 (소괄호를 이용해서 먼저 계산할 부분을 표시해줄 수 있어요!)

 

  • 변수에 저장된 값에 연산을 한 후 다시 그 값을 같은 변수에 저장할 수 있습니다.
a = 5
a = a + 3 # 5에 3을 더한 값을 다시 a에 저장
print(a)  # 8

a += 3    # 줄여 쓸 수도 있다. 같은 의미!

 

  • 나눗셈의 나머지 구하기
a//b  # 3 (몫)
a%b   # 1 (나머지)
a**b  # 49 (거듭제곱)

 

 

Bool 자료형

  • 특별한 자료형으로 참/거짓을 나타내는 불(Boolean) 자료형이 있습니다.
x = True   # 참
y = False  # 거짓

# 소문자로 쓰면 자료형으로 인식하지 않고 변수명이라 생각해 에러가 납니다~
z = true   # name 'true' is not defined

True = 1   # True/False는 변수명으로 쓸 수 없어요!

 

  • 비교연산자의 결과로 나타내기 위해 쓰여요
4 > 2      # True  크다
5 < 1      # False 작다
6 >= 5     # True  크거나 같다
4 <= 4     # True  작거나 같다
3 == 5     # False 같다
4 != 7     # True  같지 않다

 

  • 논리연산자를 이용할 수 있습니다.
a = 4 > 2  # True
not a      # False    NOT 연산자로 참을 거짓으로, 거짓을 참으로 바꿔준다.

a and b    # False    AND 연산자로 모두 참이어야 참을 반환한다.
a or b     # True     OR 연산자로 둘 중 하나만 참이면 참이다.

 

 

 

문자열

  • 파이썬에서는 '글'도 데이터로 사용할 수 있는데요, 이것을 '문자열'이라고 합니다.
# 작은 따옴표 또는 큰 따옴표. 둘 다 같아요!

a = "aa"
b = 'aa'

 

  • 따옴표로 감싸지 않으면 변수이름을 뜻하기 때문에 꼭 구분해서 써야 합니다!
a = 1
b = "a"
c = a
print(a, b, c) # 1 "a" 1

 

  • 이렇게 다양한 방법으로 만들 수 있기 때문에, 문자열에 따옴표를 포함해야 할 때 쓰면 편해요
print("I'm happy :)")

 

 

문자열 연산

  • 문자열 간의 더하기는 두 문자열을 이어 붙인 문자열을 반환합니다.
first_name = "Harry"
last_name = "Potter"

first_name + last_name  # HarryPotter
first_name + " " + last_name  # Harry Potter

a = "3"
b = "5"
a + b    # 35

 

  • 문자열과 정수를 더하면 에러발생한다.
a = "3"
a + 5    # 문자열과 숫자형은 더할 수 없어서 에러!

 

  • 문자열의 길이는 len() 함수를 써서 구할 수 있습니다!
print(len("abcde"))           # 5
print(len("Hello, Sparta!"))  # 14
print(len("안녕하세요."))      # 6

 

 

특정 자료형 뒤에. 을 붙이고 쓰는 내장 함수들을 '메서드(method)'라고 합니다!

 

  • 모든 알파벳을 대문자/소문자로 바꾸기
sentence = 'Python is FUN!'

sentence.upper()  # PYTHON IS FUN!
sentence.lower()  # python is fun!

 

  • 특정 문자를 기준으로 문자열을 나누기
# 이메일 주소에서 도메인 'gmail'만 추출하기
myemail = 'test@gmail.com'

result = myemail.split('@') # ['test','gmail.com'] ( '리스트'라는 자료형이에요 :))

result[0] # test (리스트의 첫번째 요소)
result[1] # gmail.com (리스트의 두 번째 요소

result2 = result[1].split('.') # ['gmail','com']

result2[0] # gmail -> 우리가 알고 싶었던 것
result2[1] # com

# 한 줄로 한 번에!
myemail.split('@')[1].split('.')[0]

 

  • 특정 문자를 다른 문자로 바꾸기
txt = '서울시-마포구-망원동'
print(txt.replace('-', '>')) # '서울시>마포구>망원동'

 

 

 

인덱싱과 슬라이싱

  • 문자열은 '문자들의 모임'이기 때문에 그 일부를 따로 떼어 부르는 방법이 있습니다. 한 글자 씩 부를 때는 몇 번째인지 '인덱스'를 넣어 불러서 인덱싱이라고 합니다.
f="abcdefghijklmnopqrstuvwxyz"
f[1]   # b 파이썬은 숫자를 0부터 셉니다

 

  • 문자열의 일부를 잘라낼 때는 슬라이싱이라고 해요
f[4:15]  # efghijklmno           f[4]부터 f[15] 전까지, 총 15-4=11개!

f[8:]    # ijklmnopqrstuvwxyz    f[8]부터 끝까지, 앞의 8개 빼고!
f[:7]    # abcdefg               시작부터 f[7] 전까지, 앞의 7개!

f[:]     # abcdefghijklmnopqrstuvwxyz  처음부터 끝까지

 

  • 특정 문자열로 자르고 싶을 때! split('문자열')을 활용합니다.
myemail = 'abc@sparta.co'

domain = myemail.split('@')[1].split('.')[0]
print(domain)

 

 

 

리스트와 딕셔너리

 

리스트

  • 순서가 있는, 다른 자료형들의 모임!
a = [1, 5, 2]
b = [3, "a", 6, 1]
c = []
d = list()
e = [1, 2, 4, [2, 3, 4]]
  • 리스트의 길이도 len() 함수를 사용해서 잴 수 있어요.
a = [1, 5, 2]
print(len(a))   # 3

b = [1, 3, [2, 0], 1]
print(len(b))   # 4
  • 순서가 있기 때문에, 문자열에서처럼 인덱싱과 슬라이싱을 사용할 수 있습니다!
a = [1, 5, 2]
b = [3, "a", 6, 1]
c = []
d = list()
e = [1, 2, 4, [2, 3, 4]]

 

  • 리스트의 요소가 리스트라면? 중첩해서!
a = [1, 2, [2, 3], 0]
print(a[2])      # [2, 3]
print(a[2][0])   # 2

 

  • 추가하기
a = [1, 2, 3]
a.append(5)
print(a)     # [1, 2, 3, 5]

a.append([1, 2])
print(a)     # [1, 2, 3, 5, [1, 2]]


# 더하기 연산과 비교!
a += [2, 7]
print(a)     # [1, 2, 3, 5, [1, 2], 2, 7]

 

  • 정렬하기
a = [2, 5, 3]
a.sort()
print(a)   # [2, 3, 5]
a.sort(reverse=True)
print(a)   # [5, 3, 2]

 

  • 요소가 리스트 안에 있는지 알아보기
a = [2, 1, 4, "2", 6]
print(1 in a)      # True
print("1" in a)    # False
print(0 not in a)  # True

 

 

 

딕셔너리 (dictionary)

  • 딕셔너리는 키(key)와 밸류(value)의 쌍으로 이루어진 자료의 모임입니다.
person = {"name":"Bob", "age": 21}
print(person["name"])

 

  • 딕셔너리를 만드는 데는 여러 가지 방법을 쓸 수 있습니다.
a = {"one":1, "two":2}

# 빈 딕셔너리 만들기
a = {}
a = dict()

 

  • 딕셔너리의 요소에는 순서가 없기 때문에 인덱싱을 사용할 수 없어요.
person = {"name":"Bob", "age": 21}
print(person[0])   # 0이라는 key가 없으므로 KeyError 발생!

 

  • 딕셔너리의 값을 업데이트하거나 새로운 쌍의 자료를 넣을 수 있습니다.
person = {"name":"Bob", "age": 21}

person["name"] = "Robert"
print(person)  # {'name': 'Robert', 'age': 21}

person["height"] = 174.8
print(person)  # {'name': 'Robert', 'age': 21, 'height': 174.8}

 

  • 딕셔너리의 밸류로는 아무 자료형이나 쓸 수 있어요. 다른 딕셔너리를 넣을 수도 있죠!
person = {"name":"Alice", "age": 16, "scores": {"math": 81, "science": 92, "Korean": 84}}
print(person["scores"])             # {'math': 81, 'science': 92, 'Korean': 84}
print(person["scores"]["science"])  # 92

 

  • 딕셔너리 안에 해당 키가 존재하는지 알고 싶을 때는 in을 사용합니다.
person = {"name":"Bob", "age": 21}

print("name" in person)       # True
print("email" in person)      # False
print("phone" not in person)  # True

 

  • 딕셔너리는 리스트와 함께 쓰여 자료를 정리하는 데 쓰일 수 있습니다.
people = [{'name': 'bob', 'age': 20}, {'name': 'carry', 'age': 38}]

# people[0]['name']의 값은? 'bob'
# people[1]['name']의 값은? 'carry'

person = {'name': 'john', 'age': 7}
people.append(person)

# people의 값은? [{'name':'bob','age':20}, {'name':'carry','age':38}, {'name':'john','age':7}]
# people[2]['name']의 값은? 'john'

 

 


SQL은 윈도 함수에 대해서 처음 배워서 랭크, 합계만 배웠지만 자체적으로 지원해 주는 기능을 사용하는 거라 신기했고

파이썬은 리스랑 딕셔너리를 조합해서 사용할 수 있다는 점이 흥미로웠다.