Trong hệ sinh thái DAX của Power BI, hàm CALCULATE trong Power BI cho phép bạn kiểm soát và thay đổi ngữ cảnh lọc trước khi thực hiện phép tính đó, can thiệp sâu hơn các hàm tổng hợp như SUM hay AVERAGE. Chính khả năng này biến hàm CALCULATE thành nền tảng của hầu hết các bài toán phân tích nâng cao như KPI động, so sánh theo thời gian hay tính toán tỷ lệ phần trăm.
Đọc bài viết này để hiểu rõ hơn về:
- CALCULATE trong Power BI là gì?
- Cách CALCULATE thay đổi Filter Context
- Ví dụ sử dụng CALCULATE
- Những hàm thường được dùng cùng CALCULATE
Tổng quan về hàm CALCULATE trong Power BI
CALCULATE là một trong những hàm quan trọng và quyền lực nhất trong DAX của Power BI.
Trong quy trình xử lý dữ liệu bằng Power BI, hàm CALCULATE hoạt động ở giai đoạn phân tích. Nó giúp kiểm soát cách dữ liệu được đánh giá thông qua việc điều chỉnh filter context.
Hiểu một cách đơn giản thì CALCULATE cho phép ta “định nghĩa lại” bối cảnh tính toán của một biểu thức (thường là một measure) bằng cách áp dụng một tập điều kiện lọc mới, có khả năng ghi đè hoặc bổ sung vào ngữ cảnh lọc mặc định của báo cáo.
Đọc chi tiết: Power BI là gì? Tổng quan, cách hoạt động và ứng dụng thực tế
Vì sao hàm CALCULATE quan trọng?
Các hàm tổng hợp cơ bản như SUM chỉ thực hiện tính toán trên tập dữ liệu đang chịu ảnh hưởng của filter hiện tại trong báo cáo. Bạn không thể can thiệp sâu vào phạm vi dữ liệu được tính.
Trong khi đó, hàm CALCULATE mang lại quyền kiểm soát cao hơn. Bạn có thể thêm, thay đổi hoặc loại bỏ filter một cách chủ động để đảm bảo phép tính được thực hiện đúng trên tập dữ liệu mong muốn.
Chính khả năng thao tác linh hoạt với filter context khiến CALCULATE trở thành nền tảng của các bài toán phân tích nâng cao như:
- Tính doanh thu theo điều kiện cụ thể
- So sánh số liệu theo thời gian như YoY hoặc YTD
- Xây dựng KPI thay đổi theo slicer
Đọc chi tiết: Cách sử dụng Power BI hiệu quả và các best practices cần biết
Cấu trúc cú pháp của CALCULATE
Cú pháp tổng quát của hàm CALCULATE như sau:
CALCULATE(
<expression>,
<filter1>,
<filter2>,
...
)
Trong đó:
- <expression>: là biểu thức bạn muốn tính toán, thường là một measure hoặc một phép tổng hợp như SUM, AVERAGE, COUNT… Đây là phần “kết quả cuối cùng” mà bạn muốn nhận được.
- <filter>: là một hoặc nhiều điều kiện lọc mà bạn muốn áp dụng hoặc thay đổi so với filter hiện tại của báo cáo. Mỗi filter có thể là một biểu thức logic hoặc một hàm lọc như ALL, FILTER, SAMEPERIODLASTYEAR…
Khi Power BI gặp một công thức có hàm CALCULATE, nó sẽ thực hiện theo thứ tự sau:
- Đánh giá filter context hiện tại (ngữ cảnh đang được áp dụng bởi visual, slicer, page filter…).
- Thêm, thay thế hoặc loại bỏ các bộ lọc mới được truyền vào CALCULATE.
- Tạo một filter context mới tạm thời.
- Thực thi biểu thức (expression) trong ngữ cảnh mới đó.
CALCULATE thay đổi filter context như thế nào?
Filter context đơn giản là “phạm vi dữ liệu đang được chọn để tính toán”. Phạm vi này có thể đến từ slicer, filter trên report, hoặc từ chính visual đang hiển thị.
Ví dụ, nếu bạn đang chọn Year = 2024 trên slicer, thì mọi measure trong báo cáo sẽ chỉ tính trên dữ liệu của năm 2024. Đó chính là filter context hiện tại.
CALCULATE cho phép bạn can thiệp vào phạm vi đó và nó có thể thêm điều kiện lọc mới, ghi đè điều kiện đang có hoặc loại bỏ một điều kiện lọc với các cách tiếp cận như sau:
Thêm filter mới
Giả sử báo cáo của bạn không có slicer lọc theo năm, tức là đang hiển thị toàn bộ dữ liệu từ 2021-2024:
Sales 2023 =
CALCULATE(
SUM(Sales[Amount]),
Sales[Year] = 2023
)
=> Dù người dùng không chọn năm nào, measure vẫn luôn trả về doanh thu năm 2023.
Ghi đè filter hiện có
Giả sử trên slicer, người dùng đang chọn Year = 2022. Thông thường, measure sẽ là:
Total Sales = SUM(Sales[Amount])
=> Trả về doanh thu năm 2022 vì đó là filter context hiện tại. Nhưng nếu ta viết:
Sales 2023 =
CALCULATE(
SUM(Sales[Amount]),
Sales[Year] = 2023
)
Quy trình sẽ như sau: 1. Slicer áp dụng filter Year = 2022; 2. CALCULATE nhận điều kiện mới Year = 2023; 3. Vì cùng một cột (Year), filter mới sẽ ghi đè filter cũ; 4. Power BI tính lại tổng trên dữ liệu năm 2023.
=> Kết quả là dù slicer đang chọn 2022, measure vẫn trả về doanh thu 2023. Đây là điểm nhiều người mới học DAX dễ nhầm lẫn là CALCULATE có thể ưu tiên filter bên trong nó hơn filter từ report.
Loại bỏ filter
Giả sử người dùng đang chọn Year = 2024 trên slicer. Ta muốn tạo một measure luôn hiển thị tổng doanh thu của tất cả các năm, bất kể slicer đang chọn gì thì ta sẽ viết:
Total Sales All Years =
CALCULATE(
SUM(Sales[Amount]),
ALL(Sales[Year])
)
=> Ở đây, CALCULATE không thêm filter, không ghi đè giá trị cụ thể mà loại bỏ hoàn toàn filter trên cột đó. Measure sẽ luôn hiển thị tổng doanh thu toàn bộ các năm (2021–2024), không bị ảnh hưởng bởi slicer năm.
Ví dụ sử dụng hàm CALCULATE trong Power BI
Áp dụng một điều kiện lọc (Single Filter Criteria)
Đây là trường hợp đơn giản nhất: áp dụng một điều kiện lọc duy nhất trước khi tính toán. Giả sử ta đã có measure tổng doanh thu:
Total Sales =
SUM ( Sales[Amount] )
Bây giờ bạn muốn tính doanh thu chỉ của sản phẩm “Laptop”.
Laptop Sales =
CALCULATE (
[Total Sales],
Products[Category] = "Laptop"
)
=> Ở đây, CALCULATE sẽ tạo một filter context mới với điều kiện Category = Laptop, sau đó tính lại [Total Sales] trong bối cảnh đó nên dù người dùng đang xem toàn bộ sản phẩm, measure này vẫn chỉ tính riêng Laptop.
Ghi đè hoặc bỏ qua bộ lọc với ALL()
Một trong những sức mạnh lớn nhất của CALCULATE là khả năng xóa hoặc ghi đè filter hiện có bằng hàm ALL(). Ví dụ bạn muốn luôn hiển thị tổng doanh thu toàn công ty, bất kể người dùng đang lọc sản phẩm nào.
Total Company Sales =
CALCULATE (
[Total Sales],
ALL ( Products )
)
=> Hàm ALL(Products) sẽ loại bỏ mọi filter liên quan đến bảng Products. Điều này có nghĩa là nếu người dùng chọn “Laptop” hoặc chọn “Phone” hoặc lọc theo bất kỳ danh mục nào, kết quả vẫn là tổng doanh thu của tất cả sản phẩm. Đây là cách thường dùng khi cần tính % tổng hoặc so sánh giữa một phần và toàn bộ.
Áp dụng nhiều điều kiện lọc (Multiple Filter Criteria)
Ngoài ra, CALCULATE còn cho phép ta thêm nhiều điều kiện lọc cùng lúc và các điều kiện này hoạt động theo logic AND.
Laptop Hanoi Sales =
CALCULATE (
[Total Sales],
Products[Category] = "Laptop",
Stores[City] = "Hanoi"
)
=> Trong đó, Power BI sẽ:
- Lọc Category = Laptop
- Lọc City = Hanoi
- Sau đó tính [Total Sales]
Chỉ những dòng thỏa mãn cả hai điều kiện mới được tính.
Ứng dụng nâng cao với các hàm phân tích theo thời gian (Time Intelligence)
Một trong những ứng dụng mạnh nhất của CALCULATE là trong Time Intelligence – các phép tính theo thời gian như YTD, MTD, YoY. Giả sử bạn cần tính doanh thu cùng kỳ năm trước:
Sales Last Year =
CALCULATE (
[Total Sales],
SAMEPERIODLASTYEAR ( 'Date'[Date] )
)
Hoặc tính doanh thu từ đầu năm đến hiện tại:
Sales YTD =
CALCULATE (
[Total Sales],
DATESYTD ( 'Date'[Date] )
)
=> Với 2 ví dụ trên, hàm thời gian thay đổi filter context của cột Date và CALCULATE thực hiện phép tính trong bối cảnh thời gian mới. Nhờ vậy, ta có thể tạo các chỉ số như YoY Growth, YTD, MTD chỉ với vài dòng DAX thay vì viết công thức phức tạp.
Lưu ý: Các hàm như SAMEPERIODLASTYEAR hay DATESYTD chỉ hoạt động chính xác khi tham số truyền vào là một cột ngày.
Những hàm thường dùng cùng hàm CALCULATE trong Power BI
Nhóm hàm loại bỏ hoặc điều chỉnh filter
- ALL(): Dùng để loại bỏ filter trên một hoặc nhiều cột/bảng và thường dùng khi tính % trên tổng hoặc tổng toàn cục.
- REMOVEFILTERS(): có chức năng tương tự ALL(), chuyên dùng để xóa filter. Giả sử bạn muốn “bỏ filter” trên một cột/bảng cho rõ nghĩa hơn trong code (nhìn vào biết ngay mục tiêu là xóa filter):
Total Sales No Product Filter =
CALCULATE (
[Total Sales],
REMOVEFILTERS ( Product )
)
- ALLEXCEPT(): Giữ lại filter trên một số cột và loại bỏ filter trên các cột khác của cùng bảng đó. Giả sử bạn có nhiều slicer như Year, Month, Product, Region. Bạn muốn tính doanh thu theo Region, nhưng bỏ qua các filter khác (Year/Month/Product…) thì ta dùng cú pháp:
Sales by Region (Ignore Others) =
CALCULATE(
SUM(Sales[Amount]),
ALLEXCEPT(Sales, Sales[Region])
)
Nhóm hàm lọc nâng cao
- FILTER(): Cho phép tạo điều kiện lọc phức tạp hơn thay vì chỉ so sánh đơn giản.
- KEEPFILTERS(): giúp giữ lại filter cũ và thêm điều kiện mới vào. Giả sử trang báo cáo đang có slicer Region, người dùng chọn “North + South”. Bạn muốn measure chỉ tính riêng “North”, nhưng vẫn tôn trọng các filter khác đang có (ví dụ Year, Product…) thì dùng cú pháp:
Sales North Only =
CALCULATE (
[Total Sales],
KEEPFILTERS ( Sales[Region] = "North" )
)
Nhóm hàm kiểm soát ngữ cảnh
- VALUES(): Trả về tập giá trị duy nhất của một cột trong filter context hiện tại.
- SELECTEDVALUE(): Trả về giá trị đang được chọn (thường dùng với slicer). Giả sử bạn có slicer chọn Year và bạn muốn tạo một measure phản ứng theo năm đang chọn (và nếu không chọn thì có thể trả BLANK hoặc một mặc định), ta dùng cú pháp:
Sales Selected Year =
CALCULATE(
SUM(Sales[Amount]),
Sales[Year] = SELECTEDVALUE(Sales[Year])
)
Nhóm hàm Time Intelligence
Đây là nhóm hàm được sử dụng rất phổ biến cùng CALCULATE để xử lý dữ liệu theo thời gian:
- DATESYTD(): Trả về tập hợp các ngày từ đầu năm đến ngày hiện tại trong filter context (Year-to-Date).
- DATESMTD(): Trả về tập hợp các ngày từ đầu tháng đến ngày hiện tại trong filter context (Month-to-Date).
- SAMEPERIODLASTYEAR(): Trả về tập hợp ngày tương ứng cùng kỳ của năm trước để so sánh tăng trưởng theo năm (YoY).
- DATEADD(): Dịch chuyển tập ngày hiện tại lùi hoặc tiến một khoảng thời gian xác định (ví dụ -1 năm, -1 tháng) để phục vụ phân tích so sánh.
Lỗi thường gặp khi dùng CALCULATE
Không hiểu rõ Filter Context
Đây là lỗi phổ biến nhất vì nhiều người chỉ tập trung vào công thức mà quên rằng “CALCULATE luôn thay đổi filter trước rồi mới tính biểu thức”. Khi kết quả “không giống slicer”, thường nguyên nhân là vì filter bên trong CALCULATE đã ghi đè hoặc loại bỏ filter từ report.
Lạm dụng FILTER() gây chậm hiệu năng
FILTER() sẽ tạo một bảng trung gian trước khi tính toán nên nếu dùng trên bảng lớn (hàng triệu dòng), có thể làm báo cáo chậm đáng kể. Vì vậy nếu điều kiện đơn giản (Column = Value), nên viết trực tiếp thay vì dùng FILTER.
Ghi đè filter ngoài ý muốn
Giả sử ta có:
Sales 2023 =
CALCULATE(
SUM(Sales[Amount]),
Sales[Year] = 2023
)
=> Nếu slicer đang chọn Year = 2024, measure này vẫn trả về 2023. Nhiều người nghĩ slicer bị lỗi, nhưng thực tế là filter trong CALCULATE đã ghi đè filter hiện tại. Cần hiểu rằng filter trong CALCULATE có độ ưu tiên cao hơn filter từ visual/slicer khi cùng một cột.
Nhầm lẫn giữa Row Context và Filter Context
CALCULATE hoạt động trên filter context, không phải row context. Khi dùng CALCULATE trong calculated column mà không hiểu context transition, kết quả có thể sai hoàn toàn. CALCULATE trong calculated column sẽ chuyển row context thành filter context (context transition), đây là điểm nâng cao nhưng rất quan trọng trong phỏng vấn.
Không có bảng Date chuẩn khi dùng Time Intelligence
Các hàm như DATESYTD(), SAMEPERIODLASTYEAR() yêu cầu một bảng Date riêng, được đánh dấu là Date Table và quan hệ đúng với bảng fact. Nếu không có, measure sẽ cho kết quả sai hoặc không hoạt động đúng.
Các câu hỏi thường gặp về hàm CALCULATE trong Power BI
Hàm CALCULATE có gì khác với hàm SUMX?
CALCULATE và SUMX đều là những hàm quan trọng trong DAX, nhưng chúng phục vụ hai mục đích hoàn toàn khác nhau: SUMX xử lý logic tính toán ở cấp độ dòng dữ liệu, còn CALCULATE xử lý logic ở cấp độ ngữ cảnh lọc.
- Hàm CALCULATE giúp thay đổi filter context để kiểm soát phạm vi dữ liệu được tính toán, còn SUMX là một iterator function, tức là hàm lặp qua từng dòng dữ liệu để thực hiện tính toán trước khi tổng hợp kết quả.
- CALCULATE không trực tiếp thực hiện phép cộng hay phép tính theo từng dòng. Thay vào đó, nó đánh giá một biểu thức (thường là một measure) dưới một bối cảnh lọc mới.
- Trọng tâm của CALCULATE nằm ở việc thay đổi điều kiện lọc. Trong khi đó, SUMX tạo ra row context bằng cách duyệt từng dòng trong một bảng, tính toán một biểu thức cho từng dòng, sau đó mới cộng tổng các kết quả lại.
Giả sử ta có bảng Sales gồm:
| Product | Quantity | UnitPrice | Year |
| A | 10 | 5 | 2025 |
| B | 20 | 4 | 2025 |
| C | 15 | 6 | 2026 |
Nếu cần tính Doanh thu = Quantity × Unit Price, ta không thể dùng SUM đơn thuần mà cần SUMX để tính từng dòng rồi cộng lại:
Total Revenue =
SUMX(
Sales,
Sales[Quantity] * Sales[UnitPrice]
)
Nếu chỉ dùng SUM(Quantity) * SUM(UnitPrice) thì sẽ sai logic vì phép nhân phải thực hiện theo từng dòng. Còn nếu ta muốn tính Doanh thu chỉ cho năm 2026, ta sẽ dùng CALCULATE để thêm điều kiện lọc năm:
Revenue 2026 =
CALCULATE(
[Total Revenue],
Sales[Year] = 2026
)
CALCULATE có thay đổi dữ liệu gốc trong Power BI không?
CALCULATE không thay đổi, chỉnh sửa hay ghi đè dữ liệu gốc trong bảng. Hàm này chỉ thay đổi filter context tại thời điểm tính toán measure. Nói cách khác, CALCULATE chỉ ảnh hưởng đến cách dữ liệu được đánh giá, chứ không làm thay đổi dữ liệu vật lý trong mô hình.
Việc sử dụng CALCULATE có ảnh hưởng đến hiệu năng báo cáo không?
Có thể, tùy cách sử dụng. Bản thân CALCULATE không phải là hàm “chậm”, nhưng nếu kết hợp với các hàm như FILTER trên bảng lớn hoặc loại bỏ filter quá rộng (ALL toàn bảng), nó có thể làm tăng khối lượng tính toán và khiến report chậm hơn. Hiệu năng phụ thuộc nhiều hơn vào:
- Mô hình dữ liệu
- Số lượng dòng dữ liệu
- Cách viết điều kiện filter
Có bắt buộc phải dùng CALCULATE trong mọi measure không?
Không bắt buộc. Nếu bạn chỉ cần phép tính đơn giản như dưới đây thì không cần dùng CALCULATE:
Total Sales = SUM(Sales[Amount])
CALCULATE chỉ thực sự cần thiết khi bạn muốn:
- Thêm hoặc thay đổi điều kiện lọc
- Loại bỏ filter
- Thực hiện Time Intelligence
- Tạo các phép tính động phức tạp
Vì sao kết quả khi dùng CALCULATE đôi khi “không giống slicer”?
Nguyên nhân thường là vì CALCULATE đã:
- Ghi đè filter trên cùng một cột
- Hoặc loại bỏ filter bằng ALL/REMOVEFILTERS
Điều này không phải lỗi của Power BI, mà là do filter context đã bị thay đổi theo logic của measure.
Tổng kết
CALCULATE không chỉ là một hàm bổ sung điều kiện lọc, mà là công cụ giúp bạn kiểm soát bối cảnh tính toán trong DAX. Từ việc thêm filter, ghi đè filter, xóa filter cho đến kết hợp với Time Intelligence, gần như mọi công thức DAX nâng cao đều xoay quanh CALCULATE.
Khi bạn hiểu rõ cách CALCULATE hoạt động và mối liên hệ của nó với filter context, DAX sẽ không còn là tập hợp các công thức khó nhớ mà trở thành một hệ thống logic có thể kiểm soát được. Đây cũng là bước chuyển quan trọng giúp bạn đi từ mức “biết viết measure” sang mức “thực sự làm chủ Power BI” thông qua việc kiểm soát filter context một cách chủ động.

