SQL

[MySQL] 실수, 정수 나눗셈 _ 정수 나눗셈 결과 0일 때

dydatablog 2025. 4. 29. 15:33
728x90

[목차]

- 막힌 문제 : CTR구하기

- 질문 : 100이 아니라 100.0을 곱해야하는 이유? / 정수 나눗셈 결과가 0일 때

- 답변 : 정수 나눗셈 문제

- 오늘의 배움

 

문제 : https://datalemur.com/questions/click-through-rate

 

App Clickthrough Rate | Facebook SQL Interview Question

Facebook SQL Interview Question: Write a query to calculate the click-through rate for each app.

datalemur.com

 

질문 : CTR 계산식은 (클릭 횟수 / 노출 횟수) * 100 인데 문제에서 나온 계산식은 

CTR (%) = 100.0 * 클릭 횟수 / 노출 횟수 로 계산하라고 나옴.

 

그리고 다음 수식으로 썼을 때, 답에 0으로 나옴.

중간 결과물

SELECT
  app_id,
    SUM(CASE WHEN event_type = 'click' THEN 1 ELSE 0 END) 
    / SUM(CASE WHEN event_type = 'impression' THEN 1 ELSE 0 END) AS ctr_rate
FROM events
GROUP BY app_id
;

이렇게 쓰면 3/4 = 0.75 가 ctr_rate로 나오길 바랬는데...왜...0...?

 

 

고민하다가 GPT에게 물어보니 납 득 완 료.

 

[GPT 답변]

아주 좋은 질문입니다!

당신이 제시한 두 식:

  1. 정답:
    CTR (%) = 100.0 * Number of clicks / Number of impressions
  2. 잘못된 식:
    CTR (%) = 100 * (Number of clicks / Number of impressions)

🤔 그런데 왜 2번이 잘못됐다고 했을까?

사실 수학적으로는 두 식이 완전히 동일합니다.
그런데 이 질문의 핵심은 "SQL이나 프로그래밍 언어에서는 왜 (100.0 * 클릭수 / 노출수)를 쓰는가?" 또는 **"왜 100.0을 먼저 곱하나?"**에 대한 이야기로 해석됩니다.


💡 이유 1: 정수 나눗셈 문제

대부분의 SQL 엔진(예: PostgreSQL, SQL Server 등)에서는 아래처럼 동작합니다:

SELECT 1 / 4 → 0  -- 정수끼리 나눴으므로 결과는 0
SELECT 1.0 / 4 → 0.25  -- 실수 포함 → 실수 결과

따라서 100.0을 먼저 곱하면 나눗셈이 실수로 자동 전환되어 정확한 결과가 나옵니다:

100.0 * clicks / impressions → 올바른 실수 계산

반면에 이렇게 쓰면:

100 * clicks / impressions  -- 정수 연산이면 중간 계산값 손실됨

정수끼리 먼저 나눠지면, 결과가 0이 되어버릴 수 있습니다.


💡 이유 2: 타입 강제 변환 (명시적 캐스팅 없이)

SELECT 100.0 * (clicks / impressions)  -- 이 경우 clicks / impressions가 먼저 계산됨

위 식에서 clicks / impressions가 정수 나눗셈이면 0이 됨
결과: 100.0 * 0 = 0.0


🔍 그래서 어떻게 쓰는 게 좋을까?

💯 권장 패턴:

-- 가장 안전한 방식
100.0 * clicks / NULLIF(impressions, 0)

-- 또는
100.0 * (1.0 * clicks / NULLIF(impressions, 0))

-- 또는 명시적 캐스팅
100.0 * (CAST(clicks AS FLOAT) / NULLIF(impressions, 0))

이렇게 하면 0으로 나누는 오류도 방지하고, 실수형 연산도 보장됩니다.


✅ 결론

표현 결과 문제 가능성

100.0 * clicks / impressions ✅ 정확 추천
100 * clicks / impressions ❌ 정수 나눗셈 → 0 위험
100.0 * (clicks / impressions) ⚠️ 안에 정수 나눗셈 → 0 위험

필요하시면 CTR 계산을 더 정밀하게 해주는 SQL 함수나, CTR이 낮은 앱 TOP 10을 추출하는 쿼리도 제공해드릴 수 있어요.
궁금하신가요? 😊

 

[정답 쿼리]

SELECT
  app_id,
  ROUND(100.0 *
    SUM(CASE WHEN event_type = 'click' THEN 1 ELSE 0 END) 
    / SUM(CASE WHEN event_type = 'impression' THEN 1 ELSE 0 END),2)  AS ctr_rate
FROM events
WHERE timestamp >= '2022-01-01' 
  AND timestamp < '2023-01-01'
GROUP BY app_id

 

 

[오늘의 배움]

SQL에서는 정수끼리 나눗셈하면 0으로 결과가 나온다!!
실수로 출력하고 싶으면 실수를 곱하면 된다!!

728x90