What might be an alternative way, possibly more effective, for checking if context is total. I use this measure as benchmark:
IsTotal1 = CALCULATE(COUNT(Tab[Store]), ALLSELECTED(Tab)) = COUNT(Tab[Store])
The idea is that it calculates COUNT on a table with filters removed (left side, so we get counts for all dimensions in context) and checks it against the COUNT with current context. If both are the same, we have total.
I know that using the function HASONEVALUE might be tempting:
IsTotal2 = NOT(HASONEVALUE(Tab[Store]))
However, using this approach has a serious drawback. If we make a table displaying sales by store and by product then the first measure will work and the second will fail. Moreover, if we display sales by product only the first measure will still work, and the second should be retyped to HASONEVALUE(Tab[Product]).
So I want the measure to be resistant to any change of granularity due to adding new dimension to table visual.
Based on the information you provided in the comments, it sounds like you have a page- or report level filter. In that case, you can't rely on functions such as ISFILTERED(...) or ISCROSSFILTERED(...), as these external filters or slicers could impact the result returned from these two functions.
So you have to either stick with your approach (perhaps changing COUNT(...) to COUNTROWS(Tab) could improve the performance slightly), or write something like
ISINSCOPE('Tab'[Store]) || ISINSCOPE('Tab'[Product]) || etc...
where you repeat ISINSCOPE for every column that could potentially be used to slice the data, as ISINSCOPE is the only function that distinguishes using a column on a filter/slicer vs. using it as a row/column grouping on a table/matrix visual.
Related
So I am creating a measure to count the number of sales items as follows:
Total_M = DISTINCTCOUNT(FactSales[id])
and I am creating another measure that does the same aggregation (count sales items) alongwith a filter such as:
Filtered_M = CALCULATE(DISTINCTCOUNT(FactSales[id]), Category="Electronics")
I think I can also use the first measure in the second one like:
Filtered_M2 = CALCULATE([Total_M], Category="Electronics")
Will the Filtered_M2 work as intended i.e., like Filtered_M? Is there a significant performance difference in these two? Not just for 'COUNT' but for any aggregate function being used in a similar fashion.
Apologies up front, this is going to take a second to explain but I'd rather be thorough so the problem is clear. The main problem that I am having is that people are not being properly filtered out of a matrix that I am using and I believe I have isolated the problem to some measures that I have written. Below is a picture of what I'm working with (I guess you'll have to follow the link):
My problem is that when I try to apply a filter using the slicer, you would expect the available names to be filtered out of the matrix based on if they fall under the particular team leader or director selected. However, they do not, as seen in this picture:
Clearly, people are not being filtered out because there are still values in the AnswerRatePass column and the SurveyScorePass column. I will focus on just AnswerRatePass to cut the problem in half. The purpose of AnswerRatePass is to output text to identify if the Answer Rate of a person exceeded their goal, met the goal, or missed the goal. My code for AnswerRatePass is:
AnswerRatePass = if([AnswerRateGoal] = 1,"Exceed",
if([AnswerRateGoal]=0,"Achieved","Missed"))
As you surely noticed, [AnswerRatePass] is using the value of [AnswerRateGoal] to determine what to do. I use this because it sort of simplifies the code for my Recommendation measure, which assesses if a person met their goals for both criteria, meaning we suggest to promote this person, or what their case is. My code for AnswerRateGoal is:
AnswerRateGoal =
if(ISBLANK([AnswerRate]),0,
if(values(TMD[Title])="Executive",
if([AnswerRate]>=.94,1,
if([AnswerRate]>=.92,0,-1)),
if(values(TMD[Title])="President's Club",
if([AnswerRate]>=.96,1,
if([AnswerRate]>=.94,0,-1)),
if([AnswerRate]>=.96,0,-1)
)))
If these measures (AnswerRatePass, SurveyScorePass, and Recommendation) are removed from the matrix, the slicers work exactly as expected. So, long story short, what I'm pretty sure I need is some sort of filter for these measures so that these values will disappear when using a slicer that doesn't apply to that person, allowing the individual person to also be filtered out by the slicer as well. Unless someone has a different idea, I'm pretty sure that's what I need but I haven't been able to come up with a way to do it. I'm open to any help/suggestions.
Yep, I've seen this before. I think what you want is for AnswerRatePass to return a blank if AnswerRate is blank. Try something like this:
AnswerRatePass =
IF(
ISBLANK([AnswerRate]),
BLANK(),
IF(
[AnswerRateGoal] = 1,
"Exceed",
IF(
[AnswerRateGoal] = 0,
"Achieved",
"Missed"
)
)
)
Side note: The SWITCH function is often a cleaner approach then nested IF functions.
I hope somebody can help me with some hints for the following analysis. The students may do some actions for some courses (enroll, join, grant,...) and also the reverse - to cancel the latest action.
The first metric is to count all the action occurred in the system between two dates - these are exposed like a filter/slicer.
Some sample data :
person-id,person-name,course-name,event,event-rank,startDT,stopDT
11, John, CS101, enrol,1,2000-01-01,2000-03-31
11, John, CS101, grant,2,2000-04-01,2000-04-30
11, John, CS101, cancel,3,2000-04-01,2000-04-30
11, John, PHIL, enrol, 1, 2000-02-01,2000-03-31
11, John, PHIL, grant, 2, 2000-04-01,2000-04-30
The data set (ds) is above and I have added the following code for the count metric:
evaluate
sumx(
addcolumns( ds
,"z+", if([event] <> "cancel",1,0)
,"z-", if([event] = "cancel",-1,0)
)
,[z+] + [z-])
}
The metric should display : 3 subscriptions (John-CS101 = 1 , John-PHIL=2).
There are some other rules but I don't know how to add them to the DAX code, the cancel date is the same as the above action (non-cancel) and the rank of the cancel-action = the non-cancel-action + 1.
Also there is a need for adding the number for distinct student and course, the composite key . How to add this to the code, please ? (via summarize, rankx)
Regards,
Q
This isn't technically an answer, but more of a recommendation.
It sounds like your challenge is that you have actions that may then be cancelled. There is specific logic that determines whether an action is cancelled or not (i.e. the cancellation has to be the immediate next row and the dates must match).
What I would recommend, which doesn't answer your specific question, is to adjust your data model rather than put the cancellation logic in DAX.
For example, if you could add a column to your data model that flags a row as subsequently cancelled, then all DAX has to do is check that flag to know if an action is cancelled or not. A CALCULATE statement. You don't have to have lots of logic to determine whether the event was cancelled. You entirely eliminate the need for SUMX, which can be slow when working with a lot of rows since it works row by row.
The logic for whether an action is cancelled or not moves to your source system (e.g. SQL or even a calculated column in Excel), or to your ETL (e.g. the Query Editor in Power BI) which are better equipped for such tasks. The logic is applied 1 time and then exists in your data model for all measures, instead of needing to apply the logic each time a measure is used.
I know this doesn't help you solve your logic question, but the reason I make this recommendation is that DAX is fundamentally a giant calculator. It adds things up. It's great at filters (adding some things up but not others), but it works best when everything is reduced to columns that it can sum or count. Once you go beyond that (e.g. wanting to look at the row below to adjust something about the current row), your DAX is going to get very complicated (and slow), whereas a source system or the Query Editor will likely be able to handle such requirements more easily.
What is the optimal query to obtain all the records for one specific day?
In my Weather model, 'timestamp' is a standard DateTimeField.
I'm currently using
start = datetime.datetime(2009, 1, 31)
end = start + datetime.timedelta(hours=23, minutes=59, seconds=59)
Weather.objects.filter(timestamp__range=(start, end))
but wonder if there is a more efficient method.
The way it's done in django.views.generic.date_based is:
{'date_field__range': (datetime.datetime.combine(date, datetime.time.min),
datetime.datetime.combine(date, datetime.time.max))}
There should soon be a patch merged into Django that will provide a __date lookup for exactly this type of query (http://code.djangoproject.com/ticket/9596).
Do not prematurely optimize
Index columns that your queries are based on frequently
Optimize expensive columns, like add auto-updated year, month, and day values (maybe just as a string) if and only if tests show it provides a significant speedup and only after using what already works NOW and determining it isn't viable.
I need to define a calculated member in MDX (this is SAS OLAP, but I'd appreciate answers from people who work with different OLAP implementations anyway).
The new measure's value should be calculated from an existing measure by applying an additional filter condition. I suppose it will be clearer with an example:
Existing measure: "Total traffic"
Existing dimension: "Direction" ("In" or "Out")
I need to create a calculated member "Incoming traffic", which equals "Total traffic" with an additional filter (Direction = "In")
The problem is that I don't know MDX and I'm on a very tight schedule (so sorry for a newbie question). The best I could come up with is:
([Measures].[Total traffic], [Direction].[(All)].[In])
Which almost works, except for cells with specific direction:
So it looks like the "intrinsic" filter on Direction is overridden with my own filter). I need an intersection of the "intrinsic" filter and my own. My gut feeling was that it has to do with Intersecting [Direction].[(All)].[In] with the intrinsic coords of the cell being evaluated, but it's hard to know what I need without first reading up on the subject :)
[update] I ended up with
IIF([Direction].currentMember = [Direction].[(All)].[Out],
0,
([Measures].[Total traffic], [Direction].[(All)].[In])
)
..but at least in SAS OLAP this causes extra queries to be performed (to calculate the value for [in]) to the underlying data set, so I didn't use it in the end.
To begin with, you can define a new calculated measure in your MDX, and tell it to use the value of another measure, but with a filter applied:
WITH MEMBER [Measures].[Incoming Traffic] AS
'([Measures].[Total traffic], [Direction].[(All)].[In])'
Whenever you show the new measure on a report, it will behave as if it has a filter of 'Direction > In' on it, regardless of whether the Direction dimension is used at all.
But in your case, you WANT the Direction dimension to take precendence when used....so things get a little messy. You will have to detect if this dimension is in use, and act accordingly:
WITH MEMBER [Measures].[Incoming Traffic] AS
'IIF([Direction].currentMember = [Direction].[(All)].[Out],
([Measures].[Total traffic]),
([Measures].[Total traffic], [Directon].[(All)].[In])
)'
To see if the Dimension is in use, we check if the current cell is using OUT. If so we can return Total Traffic as it is. If not, we can tell it to use IN in our tuple.
I think you should put a column in your Total Traffic fact table for IN/OUT indication & create a Dim table for the IN & Out values. You can then analyse your data based on IN & Out.