Microsoft announced at SqlBits a very important feature for DAX: Calculation Groups. These are my first impression about the new feature and the impact it will have on Analysis Services and Power BI.

UPDATE 2020-02-01: We have a series of article describing the Calculation Groups feature in more detail here: www.sqlbi.com/calculation-groups/.

The Calculation Groups provide the ability to create items that are displayed to the users as values of a column. Each of these values can apply changes to the evaluation of a measure, enabling calculation like time intelligence (year-to-date, year-over-year) to existing measures without having to enable new measures.

As of March 2019, the feature is available only on Analysis Services in SQL Server 2019 CTP 2.3. Microsoft published a detailed blog post about how to use Calculation Groups in DAX. It is definitely too early to discuss best practices and performance, but certainly this is the most important change in DAX, because it enables many scenarios that are managed using scopes in Multidimensional models (Chris Webb wrote an interesting blog post about this).

I and Alberto Ferrari waited the preview release of Calculation Groups before being able to complete the last chapter of the second edition of The Definitive Guide to DAX, which now we can reasonably expect to see on the shelf by mid-2019 (between May and July).

It will take months or probably years before we will explore all of the possibilities unlocked by Calculation Groups. I already worked on a number of scenarios beyond the obvious Time Intelligence implementation that is offered by Calculation Groups, and this is going to be huge step in DAX evolution. At the moment, the feature is available in the engine only, so we have these limitations by now (March 2019):

  • There is no UI available by Microsoft to define Calculation Groups. SQL Server Data Tools will support calculation groups before the GA release of SQL Server 2019 (within the end of 2019).
  • Tabular Editor is the only editor available now to create Calculation Groups.
  • Azure Analysis Services and Power BI Premium will have Calculation Groups before the GA release of SQL Server 2019.
  • Power BI can consume Calculation Groups, but you cannot create models in Power BI Desktop with Calculation Groups. We can assume that this feature will be available in the future, but Microsoft did not provide any release date yet.
  • The current preview does not have a number of features that will be implemented before GA release:
    • MDX query support with calculation groups (absolutely necessary to support Excel as a client).
    • Role Level Security.
    • Dynamic format strings.
    • ALLSELECTED DAX function.
    • Detail rows.

There are other important considerations about Calculation Groups:

  • Implicit measures don’t work with Calculation Groups and it will become a best practice to disable the use of implicit measures in a Tabular model. We always said that creating measure is a best practice in a semantic model, instead of relying on the automatic aggregations created by the client (such as Power BI). Now this will become official and required to support Calculation Groups.
  • DAX is not recursive, so Calculation Groups do not allow recursion. This is a good idea for controlling performance, but it requires a different approach compared to certain techniques that are possible in MDX Script by leveraging recursion.
  • Calculation Groups create specific new tables/columns that are separated from existing tables and columns of the data model. Therefore, we cannot add “virtual” items to an existing column of the data model as it is possible using the calculated members feature in Analysis Services Multidimensional.

As you see, this is just the beginning. Welcome to a new era in DAX development.

ALLSELECTED
CALCULATE modifier

Returns all the rows in a table, or all the values in a column, ignoring any filters that might have been applied inside the query, but keeping filters that come from outside.

ALLSELECTED ( [<TableNameOrColumnName>] [, <ColumnName> [, <ColumnName> [, … ] ] ] )