Mijn notitiesPraktische Power BI tips
FILTER in DAX: wanneer het hoort en wanneer CALCULATE het werk doet

Wat je in deze les leert
FILTER is een ontsnappingsroute in DAX. Wie dat weet, gebruikt hem op de goede momenten en laat hem staan op de verkeerde. Wie het niet weet, zet FILTER reflexmatig om elke filterconditie heen en vraagt zich later af waarom het rapport zo traag reageert.
Dit artikel behandelt de tweede dag van een vijfdaagse DAX-serie over filtercontext. De centrale vraag is eenvoudig: wanneer heb je FILTER nodig, en wanneer doet CALCULATE het beter zelf? Om die vraag eerlijk te beantwoorden, beginnen we bij wat FILTER als functie eigenlijk doet.
Wat FILTER eigenlijk doet
FILTER krijgt twee argumenten: een tabel en een voorwaarde. Hij loopt rij voor rij door die tabel, checkt op elke rij of de voorwaarde klopt, en geeft je een nieuwe tabel terug met alleen de rijen die door de check kwamen. De uitkomst van FILTER is altijd een tabel. CALCULATE gebruikt die tabel vervolgens om te bepalen naar welke rijen hij mag kijken bij het uitrekenen van een measure.
Dat mechanisme is logisch en precies. Maar het betekent ook dat FILTER altijd de hele opgegeven tabel doorloopt, ongeacht hoe simpel de voorwaarde is. Dat detail draagt de rest van dit verhaal.
Hetzelfde antwoord, meer werk
Neem een eenvoudige vraag: omzet in Nederland. Je kunt dat schrijven als:
CALCULATE([Omzet], Sales[Land] = "NL")
Of als:
CALCULATE([Omzet], FILTER(Sales, Sales[Land] = "NL"))
Beide formules geven exact hetzelfde antwoord, tot op de euro. Het verschil zit in hoe de engine ze verwerkt. De eerste vorm geeft CALCULATE een Booleaans filterargument op één kolom. CALCULATE kan daarmee direct naar de Nederlandse rijen springen, zonder de rest van de tabel te hoeven bekijken. De tweede vorm dwingt FILTER af om de hele Sales-tabel rij voor rij langs te gaan, alleen om te bepalen welke rijen de waarde “NL” hebben in de kolom Land.
De officiële Microsoft-richtlijn is hierover duidelijk: vermijd FILTER als filterargument in CALCULATE wanneer een Booleaanse expressie op één kolom volstaat. Technisch fout is de FILTER-variant niet. Maar je geeft de engine meer werk dan nodig, zonder dat het antwoord er beter van wordt.
Waar het misgaat op grote tabellen
Het rij-voor-rij-gedrag van FILTER wordt pas echt een probleem zodra je een measure erin zet. Neem een Sales-tabel met tien miljoen rijen en de volgende measure:
CALCULATE([Omzet], FILTER(Sales, [OmzetPerKlant] > 1000))
Voor elk van die tien miljoen rijen gaat DAX apart uitrekenen wat [OmzetPerKlant] daar oplevert, alleen om te bepalen welke rijen mogen blijven staan. Klik je op een slicer, dan herhaalt dat proces zich voor elke visual op de pagina. De formule leest netjes en het antwoord klopt, maar de engine is achter de schermen miljoenen berekeningen aan het afvinken die je met een andere aanpak had voorkomen.
Dit is klassiek de reden dat rapporten “ineens” traag worden: niet een grote dataset op zichzelf, maar een measure die per rij wordt aangeroepen binnen FILTER op een grote fact-tabel. Herken je dat patroon, dan zie je de volgende trage measure van ver aankomen.
Wanneer FILTER wél hoort
Er zijn situaties waarin je FILTER niet kunt vermijden, omdat de voorwaarde iets vergelijkt wat een Booleaan op één kolom niet kan uitdrukken.
Twee kolommen vergelijken op dezelfde rij. Een voorwaarde als Sales[Discount] > Sales[Cost] vergelijkt twee kolommen op dezelfde rij. Dat kun je niet uitdrukken als een Booleaan op één kolom, want er zijn twee kolommen betrokken. Hier is FILTER de enige route.
Een berekening in de voorwaarde. Als je filtert op Sales[Quantity] * Sales[UnitPrice] > 1000, bereken je iets per rij. CALCULATE’s Booleaanse filterargumenten gaan over kolommen, niet over rijberekeningen. Hier is FILTER onvermijdelijk.
Een measure aanroepen per rij. Soms wil je per rij controleren of een measure een bepaalde drempelwaarde haalt. Dat is precies wat FILTER doet, en CALCULATE heeft daarvoor geen equivalent.
In deze drie gevallen is FILTER niet de makkelijke weg, maar de enige weg.
De vuistregel
FILTER hoort in je measure zodra de voorwaarde iets vergelijkt wat je niet met een Booleaan op één kolom kunt uitdrukken. Zolang een enkelvoudige kolomconditie volstaat, laat je CALCULATE het werk doen en schrijf je de Booleaanse notatie.
Die regel is kort genoeg om te onthouden en groot genoeg om morgen verschil te maken in een bestaand rapport.
FILTER hoort in je measure zodra de voorwaarde iets vergelijkt wat je niet met een Booleaan op één kolom kunt uitdrukken: twee kolommen op dezelfde rij, een berekening per rij, of een measure per rij. In alle andere gevallen schrijf je de Booleaanse vorm en laat je CALCULATE het werk doen.
Open een bestaand rapport en zoek de measure die traag aanvoelt. Check per FILTER die je tegenkomt: staat er een simpele voorwaarde op één kolom in, herschrijf hem dan naar de Booleaanse vorm. Staat er een measure in en is de tabel een grote feitentabel, dan heb je de klassieke vertrager te pakken.
De volgende stap in deze serie is ALL en REMOVEFILTERS: de eerste twee functies waarmee je filters juist weer wegneemt in plaats van toevoegt. Dag 1, CALCULATE vervangt de filter op die kolom, staat hierboven als voorganger, en de spiekbrief van de hele serie legt de vijf functies op één schaal. Wil je de DAX filter-serie stap voor stap doorlopen? Bekijk de trainingen op trainerbjorn.nl.