[내일배움캠프] 데이터 트랙/본 캠프

[내일배움캠프] 28일 차 - SQL 코드카타, 데이터 전처리&시각화 2

554083460 2025. 6. 20. 21:26

 

 

 

 SQL 코드카타

 

 

문제 104

Biggest Single Number

 

☑ link

 

 

처음 답안

WITH single_num AS
(
    SELECT COUNT(num) AS count_num
    FROM MyNumbers
    GROUP BY num
)
SELECT num
FROM MyNumbers
WHERE single_num.count_num = 1;

 

최종 답안

SELECT MAX(CASE WHEN a.count_num = 1 THEN m.num ELSE NULL END) AS num
FROM MyNumbers m
LEFT JOIN 
(
    SELECT num,
           COUNT(num) AS count_num
    FROM MyNumbers
    GROUP BY num
    HAVING count_num = 1
) a
ON m.num = a.num
ORDER BY m.num DESC;

 

 

틀린 이유 

 

1. 쿼리 실행 순서를 고려하지 않고 CTE를 사용해서 본 쿼리에서 컬럼을 인식하지 못함

  • CTE가 본 쿼리보다 먼저 '정의'되는 건 맞지만
  • CTE가 항상 본 쿼리보다 먼저 실행되는 것은 아니다

2. COUNT 함수 사용 후 셀 것이 없을 때 0이 나온다는 걸 잊음

 

3. 집계함수(CASE WHEN 조건 THEN 조건충족 반환값 ELSE 조건미충족 반환값 END)

  • 조건에 column1을 쓰고, 조건충족 시 column2의 값이 반환되는 것도 가능하다는 걸 몰랐다.

 

 

개선점

 

1. 쿼리 실행 순서 ✔️

  • FROM → WHERE →  GROUP BY →  HAVING →  SELECT →  ORDER BY  → LIMIT
  • 어느 절에 CTE를 쓰는가에 따라 본 쿼리가 인식하지 못할 수도 있다.

 

2. CTE

  • 본 쿼리보다 먼저 정의
  • 항상 본 쿼리보다 먼저 실행되는 것은 아니다.
  • 서브쿼리 역시 SELECT / FROM / WHERE 또는 HAVING 중 어느 곳에 사용되느냐에 따라 실행 순서가 다르다

 

3. COUNT 함수

  • 집계할 것이 없으면 0을 반환

 

4. 집계함수(CASE WHEN)

  • 조건과 결과에 다른 컬럼 넣어 집계할 수 있다
  • SUM(CASE WHEN)
SELECT SUM(CASE WHEN date BETWEEN '2025-06-01' AND '2025-06-30' THEN price ELSE 0 END) AS june_total_price,
       SUM(CASE WHEN date BETWEEN '2025-07-01' AND '2025-07-31' THEN price ELSE 0 END) AS july_total_price
FROM table;

 

  • COUNT(CASE WHEN)
SELECT column2,
       COUNT(CASE WHEN column1 = 1 THEN 1 ELSE NULL END) AS count_column2
FROM table
GROUP BY column2;

 

 

5. 가능한 결과값 없으면 NULL 반환하도록 하기

  • LEFT JOIN 이용

 

 

 

 데이터 전처리 & 시각화 Pandas - 2

 

 

더보기

 

데이터 전처리 & 시각화 강의 3주차 : Pandas 위주로 정리 - 2

 

4. 데이터 전처리 - 데이터 선택

 

.iloc[row, column]: 인덱스 번호로 선택하기

  • 행 번호(row), 열 번호(column)를 통해 특정 행과 열 데이터 선택
data.iloc['행 번호', '열 번호']
import pandas as pd

data = {
    'A': [1, 2, 3, 4, 5],
    'B': [10, 20, 30, 40, 50],
    'C': [100, 200, 300, 400, 500]
}
df = pd.DataFrame(data)

selected_data = df.iloc[1:4, 0:2]
# 인덱스 1부터 3까지의 행과
# 0부터 1까지의 열 선택
print(selected_data)

 

.loc[row, column]: 이름으로 선택하기

  • 인덱스가 번호가 아니고 특정 문자일 경우 
data.loc['행이름', '컬럼명']
import pandas as pd

data = {
    'A': [1, 2, 3, 4, 5],
    'B': [10, 20, 30, 40, 50],
    'C': [100, 200, 300, 400, 500]
}
df = pd.DataFrame(data, index=['a', 'b', 'c', 'd', 'e'])

selected_data = df.loc['b':'d', 'A':'B']
# 레이블 'b'부터 'd'까지의 행과
# 'A'부터 'B'까지의 열 선택
print(selected_data)

 

✔️ Pandas 슬라이싱에서 주의할 점!

  • 인덱스가 번호일 때: 맨 마지막 숫자 비포함
    [1:4] → 1, 2, 3
    • .iloc[]
    • 파이썬의 전통적인 규칙 따름
  • 인덱스가 문자일 때: 맨 마지막 문자 포함
    ['a':'d'] → 'a', 'b', 'c', 'd'
    • .loc[]
    • 수학적/데이터베이스 사고방식 따름

 

1개의 컬럼 전체 선택하기

  • 1개의 컬럼 전체 선택: 리스트 슬라이싱으로
data.loc[: , '컬럼명']  # 앞의 : 부분은 모든 행을 선택하겠다는 의미

# 데이터프레임['컬럼명']으로도 동일한 값 선택 가능
data['컬럼명]
  • 여러 개의 컬럼 선택
data[['컬럼명1', '컬럼명2', '컬럼명3']]

# 내가 원하는 순서대로 데이터 선택하기
data[['컬럼명3', '컬럼명1', '컬럼명2']]

 

2개 이상의 셀 선택하기

# 1개 행, 2개 컬럼 선택
data.loc['행이름', ['컬럼명1', '컬럼명2']]

# 2개 행, 1개 컬럼 선택
data.loc[['행이름1', '행이름2'], '컬럼명1']

# 리스트 슬라이싱으로 특정 번위 지정해 선택
data.loc['행이름', '컬럼명1' :]  # '컬럼명1' : → 컬럼명 1부터 끝까지라는 의미

 

 

자료 출처

스파르타 코딩클럽 데이터 전처리 & 시각화 강의