TIL

2024-04-23

여연찌 2024. 4. 23. 20:43
  • Today

1. SQL, 파이썬 코드카타 1문제씩

2. SQL 코드카타 복습

3. SQL 라이브 세션 및 과제

4. ADsP 강의(앙상블분석)

 


  • Today I Learned

 

SQL

 

SQL 코드카타 복습

https://lyj-01.tistory.com/51

 

SQL 코드카타

번호 이름 풀이날짜 44 가격대 별 상품 개수 구하기 4/12 45 3월에 태어난 여성 회원 목록 4/5 46 대여 기록이 존재하는 자동차 리스트 구하기 4/5 48 즐겨찾기가 가장 많은 식당 정보 출력하기 4/12 55

lyj-01.tistory.com

 

69번

SELECT MONTH(start_date)
     , car_id
     , COUNT(car_id) RECORDS
FROM CAR_RENTAL_COMPANY_RENTAL_HISTORY
WHERE start_date >= '2022-08-01' AND end_date <= '2022-10-31'
GROUP BY car_id
HAVING COUNT(car_id)>= 5
ORDER BY MONTH(start_date), car_id DESC

그 안에 대여했던 car_id 를 뽑아야한다고 생각해서 end_date 도 사용했는데

이러면 안됐음 .. 

조건은 대여 시작일을 기준으로 10월까지 대여 횟수 '만' 구하는 것이기때문에

start_date 만 사용해도 된다!

 

start_date 를 기준으로 8월부터 10월까지 대여횟수 5회 이상 뽑아주기

SELECT car_id
FROM CAR_RENTAL_COMPANY_RENTAL_HISTORY
WHERE start_date BETWEEN '2022-08-01' AND '2022-10-31'
GROUP BY car_id
HAVING COUNT(car_id)>= 5

뽑아낸 car_id 를 월별,자동차id별,대여횟수 를 구해야 한다.

 

SELECT MONTH(start_date) MONTH
     , car_id
     , COUNT(car_id) RECORDS
FROM CAR_RENTAL_COMPANY_RENTAL_HISTORY
WHERE car_id IN
	(
    SELECT car_id      
    FROM CAR_RENTAL_COMPANY_RENTAL_HISTORY
    WHERE start_date BETWEEN '2022-08-01' AND '2022-10-31'   # 서브쿼리
    GROUP BY car_id
    HAVING COUNT(car_id)>= 5
    )
GROUP BY MONTH, car_id
ORDER BY MONTH(start_date), car_id DESC;

실행은 되었는데 정답이 아니었음..

이전에도 이와 동일한 사유로 해결이 안되었었는데 튜터님께 정확히 여쭤보고 왔다!

 

subQuary 내에서만 8월부터 10월까지의 횟수를 구해주었을 뿐

main Quary 에서는 8월부터 10월이 아닌

서브쿼리에서 뽑은 car_id 를 해당 테이블 내의 모든 정보에서 출력해내기 때문

 

' 해당 기간동안의  ' 라는 조건이 있기 때문에 

메인쿼리에서도 동일하게 해당 기간을 조건으로 주어야 한다.

SELECT MONTH(start_date) MONTH
     , car_id
     , COUNT(car_id) RECORDS
FROM CAR_RENTAL_COMPANY_RENTAL_HISTORY
WHERE car_id IN 
    (
    SELECT car_id
    FROM CAR_RENTAL_COMPANY_RENTAL_HISTORY
    WHERE start_date BETWEEN '2022-08-01' AND '2022-10-31'  # 서브쿼리
    GROUP BY car_id
    HAVING COUNT(car_id)>= 5
    )
    AND (start_date BETWEEN '2022-08-01' AND '2022-10-31')  # 메인쿼리
GROUP BY MONTH, car_id
ORDER BY MONTH(start_date), car_id DESC;

 

 

* UNION 과 UNION ALL 의 차이

# UNION 의 경우 테이블간의 중복값이 있으면 제거하여 통합해준다

# UNION 의 경우 중복제거를 위해 데이터를 모두 검사하기 때문에 속도가 느리다

# 중복제거가 필요없을 때에는 UNION ALL 을 사용하는 것이 좋다

 

 

 

73번

재귀쿼리

WITH RECURSIVE 테이블명 AS(
SELECT 초기값 AS 컬럼별명1			 # 비반복문
UNION ALL               		    # 두 테이블 연결
SELECT 컬럼별명1 계산식 FROM 테이블명 
WHERE 제어문             			 # 정지조건
)

 

해당 문제는 0시부터23시까지, 테이블 상에 없는 시간대도 생성을 해주어야 한다.

어떤 함수를 써야하는지는 알겠는데 

전혀 기억이 나지 않아서 이전에 포스팅 해놓은 글을 참고했다

 

재귀쿼리 함수 형식을 외워야겠다.

 

 


파이썬

문자열 다루기 기본

https://lyj-01.tistory.com/108

 

문자열 다루기 기본 # isdigit()

문자열 s의 길이가 4 혹은 6이고, 숫자로만 구성돼있는지 확인해주는 함수, solution을 완성하세요. 예를 들어 s가 "a234"이면 False를 리턴하고 "1234"라면 True를 리턴하면 됩니다. def solution(s): if len(s)==4

lyj-01.tistory.com

def solution(s):
    answer = list(s)
    for i in answer:
        if i == int(i):
            return true
        else:
            return false

list s 를 한글자씩 반복했을때 첫번째 오는 인덱스가 숫자면 true

이렇게 만들어 보려고 했는데

invalid literal for int() with base 10: 'a'

첫번째로 오는 'a' 가 문자형이다보니 오류가 발생했다

int() 는 안에 실수가 와야 형변환을 할 수 있다.. 

숫자면~ 을 풀려고 했을 때 int 로 짜면 안되었던 것!

def solution(s):
    answer = list(s)
    for i in answer:
        if i == int(i):
            return 'false'
    return 'true'

음.. 이것도 안된다.

다른 방법을 찾아봐야겠다.

def solution(s):
    answer = list(s)
    for i in answer:
        i % 1 == answer(1)
        return true

not all arguments converted during string formatting

해당 오류는 문자열 형식화 중에 모든 인수가 변환되지 않을 때 발생

변수갯수가 맞지 않다고 한다..

인덱스를 1개만 뽑으려고 했는데 그게 잘 못 된 느낌

구글링 시도!

 

def solution(s):
    if len(s)==4 or len(s)==6:   # 조건1 s의 길이가 4 혹은 6
        answer=True
    else:
        return False
    return s.isdigit()         # 조건 2 숫자로만 구성되어있는지

다른 풀이를 보던 중 조건1을 무시하고 넘어갔다는 것을 발견..

일단 조건1을 만족해야 True 이다!

그리고 True, False 를 판별하여 써주기 위해선 

소문자가 아닌 대문자로 사용해야한다! 

 

참(True), 거짓(False) 담을 수 있음

# 소문자로 쓸 경우 변수명으로 인식

# 참,거짓은 변수명으로 쓸 수 없다.

 

문자열인지 숫자인지 판별하는 함수가 있다는 것도 발견

isdigit()

# 문자열이 숫자의 형태면 True 를 반환한다.

 

 

위의 코드를 짧게 쓴다면

def solution(s):
    return s.isdigit() and len(s) in [4, 6]

이렇게도 가능..

SQL 처럼 in [,] 이 코드가 OR 을 나타내더라

len(s) in [4,6]

>> s의 길이가 4 or 6

 

 

Q. 만약 4나 6이 아닌 숫자 형태였다면? ex) s="12345"

A. if 함수 조건으로 먼저 False 가 나온다.

def solution(s):
    return s.isdigit()
    if len(s)==4 or len(s)==6:
        answer=True
    else:
        return False

* 순서를 바꿔 isdigit() 를 먼저 쓰게 된다면 결괏값이 True 로 나온다.

 

 

Q. 왜 저 코드에서는 answer=True 를 쓰는지? return 에서 answer 을 뽑아내지 않는데 안써도 되는지?

A. 쓰지 않아도 됨

def solution(s):
    if (len(s)==4 or len(s)==6) and s.isdigit(): 
        return True
    else: 
        return False

# 큰 틀인 2개의 조건을 만족시켜야 하기 때문에

1번조건 길이, 2번조건 숫자형 을 한번에 써주는 것을 추천

 

 

* 조금더 짧게 쓴다면 이렇게

def solution(s):
    if (len(s) in (4,6)) and s.isdigit(): 
        return True
    else: 
        return False

 

 

 

* 내가 처음 생각했던 숫자가 아니라면? 을 고대로 나타낸 코드!

def solution(s):
    if (len(s) == 4) or (len(s) == 6):
        for i in s:
            if i not in '1234567890':     # 1~0 까지의 숫자가 안들어있다면 False
                return False
        return True
    else:
        return False

# 숫자를 다 써주고 그 안에 없다면 을 써줘도 되었던 것 ..

if 함수 안에 for 반복문 안에 if 함수라서 

이해하기에 조금 힘들었지만 내가 생각한데로 코드를 짜려고 했다면 이렇게 해도 됐었던 것 같다!

 

 

 

* 튜터님의 꿀팁!

# 파이썬에서는 tap 키가 space bar 2번과 같다

 

 


SQL 라이브 세션

 

더보기

지난 과제 풀이

 

not 과 null 은 붙어있다고 생각하면 좋음!

1 이 아닌 이란 것을 할때 not 을 쓰고 싶다면

not in (1) 도 방법중에 하나이다

 

DATE_FORMAT()

# 위 함수는 날짜형으로 사용 가능

#  DATE_FORMAT(컬럼명,'%Y:%m') 이렇게 사용할 경우

> yyyy : mm

SUBSTR()

# 범용적으로 사용가능하다. 월까지 출력하고 싶다면 yyyy-mm-dd 라고 되어있다는 가정하에

> SUBSTR(컬럼명,1,7) 

> yyyy-mm

HAVING

# 기본적으로 GROUP BY > HAVING > SELECT 순으로 실행되지만

MySQL 에서는 예외적으로 SELECT 절에서 생성한 ALIAS 를

HAVING 절에서 적용 가능하다.

> MySQL 환경 외에서는 사용불가할 수 있기 때문에 별칭이 아닌 집계함수를 쓰는 것이 좋을 듯 하다

 

 

서브쿼리

 

중첩(일반) 서브쿼리

# WHERE 절에서 사용

# 서브쿼리의 결과에 따라 달라지는 조건절

 

스칼라 서브쿼리

# SELECT 절에서 사용

# 컬럼처럼 사용

 

인라인뷰

# FROM 절에서 사용

# 테이블 처럼 사용

# AS 구문을 사용하여 명칭을 반드시 기재해야 한다.

 

 

 


  • Next

1. SQL, 파이썬 코드카타

2. ADsP 강의

3. SQL 라이브 세션 및 과제

4. 데이터 리터러시 강의 듣기(2시간)

 

 

'TIL' 카테고리의 다른 글

2024-04-25  (1) 2024.04.25
2024-04-24  (0) 2024.04.24
2024-04-22  (1) 2024.04.22
2024-04-19  (0) 2024.04.19
2024-04-18  (1) 2024.04.18