Am creating a table from original with filter condition, where my filter value is from SELECTEDVALUE
Table is not getting filtered on SELECTEDVALUE, if I replace with a real value then it works.
Code (doesn't work)
TransGt5 =
var seletectedQuanity = SELECTEDVALUE(QuantityFilter[Quantity])
return CALCULATETABLE(
Transactions,
FILTER(
ALL(Transactions),
Transactions[Quantity] >= seletectedQuanity
))
Code works file with hard coded value:
TransGt5 =
var seletectedQuanity = SELECTEDVALUE(QuantityFilter[Quantity])
return CALCULATETABLE(
Transactions,
FILTER(
ALL(Transactions),
Transactions[Quantity] >= 3
))
what am doing wrong?
That's not how Power BI works conceptually.
DAX can be used in 2 ways: to query data, and to define data (similar to SQL).
For queries, you can create DAX measures. They are executed in the run time and can respond to slicers and other user actions.
For calculated tables and columns, you can also write DAX code, but it's executed only in design time, when you create the code or refresh the data. It does not run as a query, and can not respond to user actions. The fact that you used DAX to create a table is irrelevant - the result is a static table, identical to the imported tables.
The only way to make it work is to build a measure. Inside measures, you can calculate tables, store them in variables, use them to calculate whatever you need and then publish a result. The result will be responsive to slicers.
For example, it could be something like:
Example =
VAR seletectedQuanity = SELECTEDVALUE ( QuantityFilter[Quantity] )
VAR FilteredTable =
CALCULATETABLE (
Transactions,
Transactions[Quantity] >= seletectedQuanity )
VAR Result = SUMX ( FilteredTable, Transactions[Quantity] )
RETURN Result
(although for this example, there are easier ways to achieve the same results, without the calculated table)
Related
I'm freshly new to DAX & PowerBI, I tried to create a measure column that will count the number of child of each parent has.
The table is something like this (please understand this table structure might be not ideal, but I can't change the existing).
What I expect is to create a new column that will count how many "child" that the "parent" has based on "Parent ID". Like this.
I've tried using this formula but it returns error
Childcount =
COUNTROWS(
FILTER(
Table,
FILTER(
Table,
Table[Parent ID] <> BLANK()
) = Table[ID]
)
Thank you for your help.
This can be done. Just a quick note, there are two types of calculations you canmake in Power BI: measure and calculated column. I Guess you're in nedd of a calculated column so here's a solution using calculated columns.
First create a calculated column like this:
Parent ID =
var idcol = [id]
var result =
IF(
[Type] = "Child",
CALCULATE(
MAX('Data'[ID]),
FILTER(
ALL('Data'),
'Data'[Type] = "Parent" && 'Data'[ID] < idcol
)
),
BLANK()
)
return
result
Then you can create a second calculated column like this:
Childcount =
var idcol = [ID]
return
CALCULATE(
COUNT(Data[Parent ID]),
FILTER(
ALL(Data),
'Data'[Parent ID] = idcol
)
)+0
Since you're new to Power BI/Dax I would highly recomend you check youtube and sqlbi for free introductory videos. Before you understand the concept of how calculations are performed in Power BI you're gonna have a tough time. But it's worth the time investment!
I have a slicer, called COUNTRY and applied to table MY_TABLE. When I calculate a measure, everything works as expected:
-- calculates distinct count only for COUNTRY = x
Some Measure = DISTINCTCOUNT('MY_TABLE'[SOME_COLUMN])
The problem is SUMMARIZE ignores slicer selection:
-- calculates distinct count accross all countries: x, y, z, etc.
Calculated Table =
RETURN SUMMARIZE(
'SOME_TABLE',
[CATEGORY],
"COUNT", DISTINCTCOUNT('SOME_TABLE'[SOME_COLUMN])
)
How to make SUMMARIZE take into account slicers?
Only Measures are "responsive", calculated tables and columns get calculated and created once, when the data are loaded.
Note that if a calculated table is used inside a measure it will behave correctly, but as you may know, a measure must return a scalar value and not a table. (ie you can use summarize inside a measure, you can then filter the obtained table and return the sum of one column)
Of course, you can filter calculated table with a slicer. If you can, go for SUMMARIZECOLUMNS because this function is better optimized then SUMMARIZE, and has arguments for filtering.
Filtering SUMMARIZECOLUMNS
If you want to stick to SUMMARIZE, you can filter your table by wrapping it with CALCULATETABLE.
Calculated Table =
CALCULATETABLE (
SUMMARIZE (
'SOME_TABLE',
[CATEGORY],
"COUNT", DISTINCTCOUNT ( 'SOME_TABLE'[SOME_COLUMN] )
),
Dim[Color]
= SELECTEDVALUE ( Slicer[SlicerValues] )
)
Should FILTER be used inside or outside of SUMMARIZE?
I have two tables:
A calendar table with both dates and hours.
And a table that contains incidents, with start time and end time in addition to set of attributes (only one, incident_code, in the example table).
For a specific date range, I want to show how many incidents occurred each hour.
The following measure works, but struggles when the incident table becomes large and there is several slicers
incidentCnt =
CALCULATE(
COUNTROWS(incidents);
FILTER(
incidents;
incidents[start_datetime] < MAX(date_hour[datetime]) &&
incidents[end_datetime] > MAX(date_hour[datetime])
)
)
What would be a more efficient way to calculate this with DAX in Power BI?
EDIT: This expression will work with the data presented above (minor edits to the accepted answer).
Expanded_Incidents =
GENERATE(
incidents;
SELECTCOLUMNS(
GENERATESERIES(
DATE(
YEAR(incidents[start_datetime]);
MONTH(incidents[start_datetime]);
DAY(incidents[start_datetime])
) + TIME(HOUR(incidents[start_datetime]);0;0);
incidents[end_datetime];
TIME(1;0;0)
);
"Expanded_incident_time"; [Value]
)
)
A more effectiv way would be to expand the incidents table so that each incident occurs for each time between the start and end datetime. This you can do with a calculated table like this:
Expanded_Incidents =
GENERATE(
incidents;
SELECTCOLUMNS(
GENERATESERIES(
incidents[start_date];
incidents[end_date];
TIME(h;m;s)
);
"Expanded_incident_time"; [Value]
)
)
Change the TIME(h;m;s) to the time resolution of your choosing.
Then make a relationship between your dateTime dim table and the [Expanded_incident_time] column (this should be a 1:*). Then you only have to make a measure which counts the number of rows in the new table. This will give you the number of active incidents during a specific time and I believe it will be faster than reitterating over the table each time.
How to filter all products on promotion? Say we have two tables Sales and Budget without physical relationship. Here model is simplified and let's assume that it is the case, we cannot create physical relationship. We have to use virtual relationship.
We can see summary:
The two first columns are of the Sales table. The third column BudgetTreats is a measure:
BudgetTreatas =
CALCULATE (
SUM ( Budget[amount] ),
TREATAS (
VALUES ( Sales[id] ),
Budget[id]
)
)
Now I would like to resolve two things:
How to make a slicer to filter out only the products (id) which have BudgetTreatas?
How to create a measure for calculating sales but only for products which have a budget? So analogous measure as BudgetTreatas presented above.
And of course sample data: DAX TREATS.pbix
I posted an answer to my question but it is not to show an answer but rather to show working solutions, and give you idea on expected results. I would be grateful for any answer or comments.
References:
The Logic behind the Magic of DAX Cross Table Filtering
Virtual Filters Using TREATAS
How To Use The TREATAS Function - Power BI & DAX
Creating Virtual Relationships Using TREATAS - Advanced Power BI Technique
Measure calculating Sales filtered by ids in Budget table.
Surprisingly this is not working:
//not working:
SalesFilteredByBudget1 =
CALCULATE (
[Sales],
TREATAS ( VALUES ( Budget[id] ), Sales[id] )
)
It seems we need an extra table. If we add to the model a Bridge table with all sales id and connect it to Sales table on id (without connecting it to Budget table!) we may resolve the issue.
//works:
SalesFilteredByBudget2 =
CALCULATE (
[Sales],
TREATAS ( VALUES ( Budget[id] ), Bridge[id] )
)
So it seems filters propagate further from tables used in TREATAS( VALUES on the tables connected by physical relations.
If we want to make a measure without Bridge table we can make extra table as a table variable.
// works:
SalesFilteredByBudget3 =
VAR Lineage =
TREATAS ( VALUES ( Budget[id] ), Sales[id] )
VAR tbl =
CALCULATETABLE ( Sales, KEEPFILTERS ( Lineage ) )
VAR result =
CALCULATE ( SUMX ( tbl, [amount] ) )
RETURN
result
I have a classic datawarehouse with records. Each record has a valid_from and a valid_to date.
Now I want to set a filter in PowerBI. The idea is that the user somehow sets a date and all records for which this date falls between valid_from and a valid_to should be available in PowerBI. Thus granting the user the possibility of timetravelling through the data.
This seems like a very standard task but I can't find how to do it.... Suggestions?
Given the vague question without explicit details, I'll have to make some assumptions. I'll assume that you have a date slicer that populated from a parameter table unrelated to your data table and that you have a set of measures you use in your visual(s) to display the records you're interested in.
Given those assumptions, you can write a measure to filter your an existing measure along these lines:
FilteredMeasure =
VAR SelectedDate = SELECTEDVALUE ( DateSlicer[Date] )
RETURN
CALCULATE (
[ExistingMeasure],
FILTER (
DataTable,
DataTable[valid_from] <= SelectedDate
&& SelectedDate < DataTable[valid_to]
)
)
Here's another similar but not completely equivalent formulation:
FilteredMeasure =
VAR SelectedDate = SELECTEDVALUE ( DateSlicer[Date] )
RETURN
CALCULATE (
[ExistingMeasure],
DataTable[valid_from] <= SelectedDate,
DataTable[valid_to] > SelectedDate
)