조건에 따라 다른 값을 보여주고 싶을 때 가장 먼저 떠오르는 함수가 IF입니다. 엑셀의 IF와 모양이 거의 같아서 금방 쓰게 되는데, DAX에서는 몇 가지가 조금 다르게 동작합니다. else를 생략하면 빈 값이 나온다는 점, 두 결과의 데이터 형식이 다르면 어떻게 되는지, 합계 줄에서 조건이 어떻게 평가되는지, 그리고 분기 안에서 식이 언제 계산되는지입니다. 이 글에서는 IF의 기본 문법과 함께 실무에서 자주 쓰는 세 가지 상황(계산 열의 등급 나누기, 조건부 측정값, 합계 줄의 함정)을 같은 데이터로 정리합니다.
문법
IF( <조건>, <참일 때 값> [, <거짓일 때 값>] )
Microsoft 문서의 설명대로 IF는 조건을 확인해서, 참이면 두 번째 인수를, 아니면 세 번째 인수를 돌려줍니다. 세 번째 인수는 생략할 수 있고, 생략하면 빈 값(BLANK)이 반환됩니다. 반환값은 참일 때 값, 거짓일 때 값, 또는 빈 값 중 하나입니다.
Power BI Desktop에서 쓰는 두 가지 방법
메뉴 이름은 Power BI 버전과 언어 설정에 따라 조금 다를 수 있다는 점을 먼저 말씀드립니다. IF는 두 곳에서 자주 씁니다.
- 측정값: 리본의 “새 측정값”(영문판은 New measure)을 눌러 수식 입력줄에 식을 적습니다. 보고서의 각 셀이 가진 필터 상태에 맞춰 다시 계산됩니다.
- 계산 열: 테이블을 선택하고 “새 열”(영문판은 New column)을 눌러 식을 적습니다. 행마다 값이 계산되어 모델에 저장됩니다.
예제 데이터
앞선 SUMX 함수 글의 데이터와 이어지는 가상 데이터입니다. 금액은 수량 × 단가를 미리 계산해 둔 값입니다. 결과는 Power BI에서 돌린 화면이 아니라 직접 구한 값이니, 같은 식을 본인 데이터에 적용해서 확인해 보세요.
| 주문 | 상품 | 금액 |
|---|---|---|
| 1 | 노트북 | 120 |
| 2 | 마우스 | 12 |
| 3 | 모니터 | 40 |
| 4 | 마우스 | 20 |
| 5 | 노트북 | 200 |
총매출 = SUM( 주문[금액] )
총매출은 120 + 12 + 40 + 20 + 200 = 392이고, 상품별로는 노트북 320, 마우스 32, 모니터 40입니다.
실무 시나리오 1: 계산 열로 등급 나누기
주문 금액에 따라 “대형”, “중형”, “소형”으로 나누는 계산 열을 만들어 보겠습니다. 조건이 둘이라 IF를 한 번 겹쳐 씁니다.
주문등급 =
IF(
주문[금액] >= 100,
"대형",
IF( 주문[금액] >= 30, "중형", "소형" )
)
| 주문 | 금액 | 주문등급 |
|---|---|---|
| 1 | 120 | 대형 |
| 2 | 12 | 소형 |
| 3 | 40 | 중형 |
| 4 | 20 | 소형 |
| 5 | 200 | 대형 |
대형 2건, 중형 1건, 소형 2건입니다. 이 구조는 Microsoft 문서가 보여주는 가격대 분류 예제와 같은 모양이고, 문서는 이렇게 IF를 여러 번 겹쳐야 할 때는 SWITCH 함수가 더 깔끔할 수 있다고 안내합니다. 조건이 늘어날수록 괄호가 깊어져서 읽기 어려워지기 때문입니다. SWITCH는 별도 글에서 다룹니다.
세 번째 인수를 생략하면 어떻게 되는지도 확인해 보겠습니다.
대형표시 =
IF( 주문[금액] >= 100, "대형" )
1번과 5번 주문만 “대형”이고, 나머지 세 건은 거짓일 때 값이 없으므로 빈 값이 들어갑니다. 빈 값이 의도한 결과인지, “해당 없음” 같은 글자를 보여줘야 하는지는 보고서에서 어떻게 보이길 원하는지에 따라 정하세요.
실무 시나리오 2: 조건부 측정값과 합계 줄의 함정
“총매출이 100 이상인 상품만 매출을 보여주고 싶다”는 요청을 IF로 풀어 보겠습니다.
큰상품매출 =
IF( [총매출] >= 100, [총매출] )
세 번째 인수를 생략했으니 조건이 거짓이면 빈 값입니다. 상품별 표에 올리면 이렇게 나옵니다.
| 상품 | 총매출 | 큰상품매출 |
|---|---|---|
| 노트북 | 320 | 320 |
| 마우스 | 32 | (빈 값) |
| 모니터 | 40 | (빈 값) |
| 합계 | 392 | 392 |
노트북 320만 보이는데 합계 줄은 320이 아니라 392입니다. 오류가 아닙니다. 측정값은 줄마다 따로 계산되는데, 합계 줄은 필터 없이 전체를 대상으로 새로 계산합니다. 합계 줄의 총매출은 392이고 이것은 100 이상이므로 조건이 참이 되어 392가 나오는 것입니다. 화면에 보이는 줄의 합(320)과 다른 이유가 이것입니다. 앞선 AVERAGE 함수 글에서 본 “합계 줄은 필터 없이 새로 계산한 값”이라는 원리와 같습니다.
합계 줄도 보이는 줄의 합에 맞추고 싶다면 상품 목록 위에서 반복하는 방식으로 바꿉니다.
큰상품매출_합계일치 =
SUMX(
VALUES( 주문[상품] ),
IF( [총매출] >= 100, [총매출] )
)
상품 목록(VALUES)을 한 줄씩 돌면서 각 상품의 총매출이 100 이상일 때만 값을 내보내고, SUMX가 그 결과를 더합니다. 조건이 거짓인 상품은 빈 값이라 더해지지 않아서, 합계 줄도 노트북의 320 하나가 됩니다. 반복 안에서 측정값을 부르면 “지금 도는 상품”이 필터로 바뀌는 컨텍스트 전환이 일어납니다(CALCULATE 함수 글 참고). 어느 쪽이 맞는지는 보고서가 보여주려는 숫자에 달려 있습니다. “전체 매출이 100 이상인가”를 묻는다면 앞의 식이, “보이는 줄의 합”을 원한다면 반복하는 식이 맞습니다.
실무 시나리오 3: 빈 값을 검사하고 대체하기, 그리고 데이터 형식
DIVIDE 함수 글에서 본 것처럼, 목표가 비어 있는 지역의 달성률은 빈 값이 됩니다. 이 빈 칸에 “목표 없음”이라는 글자를 보여주고 싶다면 이렇게 쓸 수 있습니다.
달성률표시 =
IF(
ISBLANK( [총목표] ),
"목표 없음",
DIVIDE( [총매출], [총목표] )
)
| 지역 | 총매출 | 총목표 | 달성률표시 |
|---|---|---|---|
| 서울 | 300 | 250 | 1.2 (120%) |
| 부산 | 120 | 200 | 0.6 (60%) |
| 광주 | 50 | (빈 값) | 목표 없음 |
식은 단순한데 이 측정값에는 주의할 점이 있습니다. 참일 때 값은 글자(“목표 없음”)이고 거짓일 때 값은 숫자입니다. Microsoft 문서는 두 결과의 데이터 형식이 다르면 IF가 여러 형식이 섞인(variant) 값을 돌려줄 수 있다고 설명합니다. 숫자끼리일 때는 하나의 형식으로 맞추려고 한다는 설명도 있어서, 예를 들어 IF( 조건, 1.0, 0 )은 소수 형식만 돌려주지만 IF( 조건, TRUE(), 0 )은 참/거짓과 숫자가 섞여 나올 수 있다는 것입니다. 이렇게 글자와 숫자가 섞인 측정값은 백분율 서식을 적용하기 어렵고 시각화에서 정렬이나 합계도 곤란해집니다. 가능하면 한 측정값은 한 가지 형식으로 두고, 빈 칸에 글자를 보여주는 것은 서식이나 조건부 서식 쪽에서 처리하는 것을 고려해 보세요.
분기 안에서 식은 언제 계산될까
DAX Guide는 IF가 필요한 분기만 계산하는 지연 평가(lazy evaluation)를 한다고 설명합니다. 그런데 이 최적화를 모르고 쓰면 성능이 떨어지는 경우가 있습니다. SQLBI의 설명을 요약하면, 변수를 IF나 SWITCH 바깥에서 먼저 정의하면 그 변수들은 분기와 상관없이 모두 계산됩니다. 분기에서 쓸 값은 가능하면 그 분기 안에서 변수로 정의해야 필요한 것만 계산한다는 것입니다. 다만 IF의 첫 번째 인수(조건)에서 쓰는 변수는 바깥에서 정의해도 상관없다고 SQLBI는 덧붙입니다.
-- 두 측정값을 분기와 상관없이 항상 계산하는 방식
결과_나쁜예 =
VAR 매출값 = [총매출]
VAR 원가값 = [총원가]
RETURN
IF( 매출값 >= 100, 매출값 - 원가값, 0 )
-- 분기 안에서 필요할 때만 계산하는 방식
결과_좋은예 =
IF(
[총매출] >= 100,
VAR 매출값 = [총매출]
VAR 원가값 = [총원가]
RETURN 매출값 - 원가값,
0
)
위 예제는 개념을 보여주기 위한 형태입니다. 이런 최적화가 실제로 의미가 있는지는 모델 크기와 식의 비용에 달려 있고, 성능은 DAX Studio 같은 도구로 측정해야 알 수 있습니다. 반대로 두 분기를 항상 계산하는 방식이 더 빠를 수도 있어서, 이를 강제하는 함수(IF.EAGER)가 따로 있습니다. DAX Guide는 IF.EAGER를 두 결과 식을 항상 계산하는 방식이라고 설명하며, 실제로 빠르다는 것을 측정한 뒤에만 쓰라고 안내합니다.
쓰지 말아야 할 때
- 조건이 세 개 이상으로 겹칠 때: IF를 깊게 겹치기보다 SWITCH가 읽기 쉽습니다.
- 분모가 0일 수 있는 나눗셈: IF로 분모를 직접 검사하기보다 DIVIDE가 간결하고 최적화되어 있습니다. DAX Guide도 IF가 빈 값을 돌려주는 경우 DIVIDE가 더 빠른 계획을 만들 수 있다고 설명합니다.
- 테이블을 돌려줘야 할 때: IF는 값(스칼라)만 돌려줍니다. 두 분기가 모두 테이블을 반환하는 식은 오류가 납니다.
- 한 측정값에 글자와 숫자를 섞어야 할 때: 형식을 하나로 맞추는 방법을 먼저 찾아보세요.
알아둘 점
- 세 번째 인수를 생략하면 빈 값이 반환됩니다.
- 여러 IF를 겹치면 괄호가 깊어집니다. 괄호가 모두 닫혔는지 확인하세요.
- DAX에서 참/거짓 비교 결과를 그대로 열로 쓸 수도 있지만, 보고서에서는 글자(“예”, “아니오”)로 바꿔 보여주는 경우가 많습니다.
- 지역 설정에 따라 인수 구분자가 쉼표 대신 세미콜론일 수 있습니다. 식을 붙여 넣었는데 오류가 난다면 먼저 확인해 보세요.
자주 하는 실수
- 합계 줄에서 조건이 어떻게 평가되는지 모르고 값이 맞지 않는다고 판단: 합계 줄은 필터 없이 새로 계산합니다.
- else를 생략하고 빈 값이 나오는 것을 오류로 생각: 정상 동작입니다.
- 글자와 숫자를 한 측정값에 섞음: 서식과 정렬이 곤란해집니다.
- 변수를 IF 바깥에 모두 정의: 필요 없는 분기까지 계산될 수 있습니다.
비슷한 함수
- SWITCH: 조건이 여러 개일 때 IF 겹침을 대신합니다.
- IFERROR: 오류가 났을 때 대체값을 돌려줍니다.
- COALESCE: 첫 번째 빈 값이 아닌 값을 돌려줍니다.
- IF.EAGER: 두 분기를 항상 계산하는 방식의 IF입니다.
정리
IF는 “조건이 참이면 A, 아니면 B”라는 가장 기본적인 분기이고, else를 생략하면 빈 값이 나온다는 점, 합계 줄은 필터 없이 새로 평가된다는 점, 한 측정값은 한 가지 형식으로 두는 것이 좋다는 점만 기억해도 대부분의 혼란을 피할 수 있습니다. 조건이 많아지면 SWITCH를, 나눗셈은 DIVIDE를 먼저 떠올려 보세요. 예제는 가상 데이터이니 본인 모델의 열 이름으로 바꿔 직접 확인해 보시고, 동작은 버전에 따라 다를 수 있어 공식 문서도 함께 보시길 권합니다.
참고한 자료
- Microsoft Learn, IF function (DAX): https://learn.microsoft.com/en-us/dax/if-function-dax
- DAX Guide, IF: https://dax.guide/if/
- DAX Guide, IF.EAGER: https://dax.guide/if-eager/
- SQLBI, Optimizing IF and SWITCH expressions using variables: https://www.sqlbi.com/articles/optimizing-if-and-switch-expressions-using-variables/