MDX: How to get MAX value and the hour when MAX value occurs for each day - grouping

I have a cube with defined Hour dimension and a column in the fact table named numberofoccurrances. How can I get the maximum number of occurrances and the hour when the value happened for each day. I have tried the following
SELECT [Measures].[numberofoccurrances] ON 0,
TOPCOUNT([Hour].[Hour].MEMBERS, 1, [Measures].[numberofoccurrances])
ON 1
FROM [all_measurements]
which finds the hour where the max value happened but the sums up all values for that hour and return wrong value.
Is there a way to get each hour with max value for a day in two columns?

You need to use rank() and filter function. Take a look at the example below.
The query below list the internet sales for year -months
SELECT
{[Measures].[Internet Sales Amount]} ON COLUMNS,
non empty ({[Date].[Calendar Year].[CY 2011],[Date].[Calendar Year].[CY 2012],[Date].[Calendar Year].[CY 2013]},[Date].[Month of Year].[Month of Year])
ON ROWS
FROM
[Adventure Works]
Results
Now rank the months within years, and filter them first rand
WITH
MEMBER [Measures].[Monthly_Ranking_InternetSales] AS
RANK( [Date].[Month of Year].CurrentMember,
ORDER( [Date].[Month of Year].[Month of Year].Members , [Measures].[Internet Sales Amount], BDESC)
)
SELECT
{[Measures].[Internet Sales Amount]} ON COLUMNS,
non empty
filter( ({[Date].[Calendar Year].[CY 2011],[Date].[Calendar Year].[CY 2012],[Date].[Calendar Year].[CY 2013]},
ORDER ([Date].[Month of Year].[Month of Year], [Measures].[Monthly_Ranking_InternetSales] , BASC )
),[Measures].[Monthly_Ranking_InternetSales] <2)
ON ROWS
FROM
[Adventure Works]
Result

Related

Calculate date diff between column date for each row and min slicer date

I think that the following formula summarize pretty well what I want to achieve:
date diff =
ABS (
DATEDIFF (
data_table[login_date],
SELECTEDVALUE ( 'Date'[Date] ),
DAY
)
)
but it returns me the following error
A single value for column 'login_date' in table 'data_table' cannot be determined. This can happen when a measure formula refers to a column that contains many values without specifying an aggregation such as min, max, count, or sum to get a single result.
In other word I want have a column in my data_table with date diff calculated dynamically based on min slicer date selection.
My final goal is to filter out dynamically users that has not been logged for the last 3 months based on the slicer date range.
Here is the dataset
user_id, login_date
111, 01/02/2021
222, 02/15/2021
444, 03/15/2021
555, 01/15/2021
I want user ID to be filtered out when the number of days between the max date of the date range and the day of the last connection is higher than 90 days.
Edit
I'm adding a different formula I'm working on but having few issues to make it work
active users = CALCULATE( DISTINCTCOUNT(data_table[id]), ( FILTER ( VALUES ( data_table[id] ), DATEDIFF(IF( ISBLANK(SELECTEDVALUE(data_table[login_date])),[Min range date],SELECTEDVALUE(data_table[login_date])),[Max range date],DAY) < 90 ) ))
You can't have a dynamically calculated column, but you can use a measure to do this. The issue that you have with your calculation is that it needed to do a row by row evaluation, rather than over a column. That is why you get an 'A single value for column 'login_date' in table 'data_table' cannot be determined' error.
In this case you can use SUMX, as this is a iterator and it will do row by row. So using the following measures:
Selected Date = SELECTEDVALUE('Calendar'[Date])
This reads the date selected. You can wrap it with a MIN/MAX if needed depending on how your slicer is set up. You can change the slicer to single select, it you just want one value.
Date Calc = SUMX('Table', DATEDIFF('Table'[Login_date], [Selected Date], DAY))
This uses SUMX to calculate on a row by row level.
You can then use this measure to drive your visual. In this example I've filtered out those over 30 days since the login
If you choose a new date, it will recalculate straight away. This should set you on the right path for your use case.

Power Bi - Total for Period Year Prior Based On SelectedValue Period

Problem:
Calculate the total for period of prior year of the period(s) selected in slicer. Table has amount, period, and a date, ie 11/1/2020 for period 11/2020, based on the period.
Attempted:
Slicer periods selected are 10/2020 and 11/2020.
Table visual contains the period and amount columns. Data Model Table contains columns, account, amount, period, and period date. Multiple accounts per period will have the same period date, to sort the periods. Example, account 1 through 3 will all have 11/1/2020 as period date for period 11/2020. Calculated Measure created to calculate last year amount is as follows:
Total For Period Last Year =
CALCULATE(
Sum(‘Table’[Amount])
, Filter(
‘Table’
,SAMEPERIODLASTYEAR(‘Table’[Period Date])
)
)
Results:
Calculated measure is added to table but only shows the amount for the period selected in slicer and not the period for the same period but of the prior year.
So 10/2020 amount would be $2000 and the calculation should show amount for 10/2019 with ie $1500.
Period | Amount | Total For Period Last Year
11/2020 $2000 $2000
10/202. $1500 $1500
Desired Result:
Period | Amount | Total For Period Last Year
11/2020 $2000 $1500
10/2020 $1500 $1000
To use time intelligence functions a well formed date table should be used. It's possible to create one using various techniques; an easy one can be found here
DAX 101: Creating a simple date table in DAX
That said, the error in your code is that you iterate over the Table part in the current filter context. You might see a better result (but maybe still not correct, because a Date table is missing, using ALL( 'Table' ) instead of just 'Table'. This way you would FILTER over the whole table instead of just the portion in the current period.
Total For Period Last Year =
CALCULATE(
SUM( 'Table'[Amount] ),
FILTER( ALL( 'Table' ), SAMEPERIODLASTYEAR( 'Table'[Period Date] ) )
)
I'm not sure, since I never use auto date/time, but this could also work by using the Power BI generated Date table when auto date/time is enabled (and if I correctly remember the synstax on how to use it)
Total For Period Last Year =
CALCULATE(
SUM( 'Table'[Amount] ),
FILTER( ALL( 'Table' ), SAMEPERIODLASTYEAR( 'Table'[Period Date].[Date] ) )
)
To use Time intelligence like sameperiodlastyear, you must use date table (Mark as Date Table). Read this description:
https://dax.guide/sameperiodlastyear/#
In order to use any time intelligence calculation, you need a well-formed date table. The Date table must satisfy the following requirements:
All dates need to be present for the years required. The Date table must always start on January 1 and end on December 31, including all the days in this range. If the report only references fiscal years, then the date table must include all the dates from the first to the last day of a fiscal year. For example, if the fiscal year 2008 starts on July 1, 2007, then the Date table must include all the days from July 1, 2007 to June 30, 2008.
There needs to be a column with a DateTime or Date data type containing unique values. This column is usually called Date. Even though the Date column is often used to define relationships with other tables, this is not required. Still, the Date column must contain unique values and should be referenced by the Mark as Date Table feature. In case the column also contains a time part, no time should be used – for example, the time should always be 12:00 am.
The Date table must be marked as a date table in the model, in case the relationship between the Date table and any other table is not based on the Date.
Remarks
The dates argument can be any of the following:
A reference to a date/time column. Only in this case a context transition applies because the column reference is replaced by
CALCULATETABLE ( DISTINCT ( ) )
A table expression that returns a single column of date/time values.
A Boolean expression that defines a single-column table of date/time values.
The result table includes only dates that exist in the dates column.
Internally SAMEPERIODLASTYEAR corresponds to the following call of DATEADD:
DATEADD ( <Dates>, -1, YEAR )

How to get the first instance of a column

I have a table of 21 million rows with dates stretching all the way from 2009.
For the purpose of this question, only three columns are concerned. It has a date column (called settlement date) and one date can occur on thousands of rows. The other column is Net Sales and this has dollar values and the final column is fiscal year. I did a calculated column to find the cumulative values:
Commulative =
CALCULATE (
SUM ( 'IP Net Sales'[Net Sales] ),
FILTER (
ALLEXCEPT ( 'IP Net Sales', 'IP Net Sales'[Fiscal Year] ),
'IP Net Sales'[Settlement Date] <= EARLIER ( 'IP Net Sales'[Settlement Date])
)
)
However, I have ran into the scenario below where on the same day, I am getting a value that sums up all the Net Sales that happened on that day and this value is duplicated for the entire day. This itself is fine, however, when i do a line graph, it sums all these values whereas i only want one instance of this cumulative value per day. How to go on about doing?

Power BI dynamic ranking with some blank values and using slicers

I have a table with 15 people that each month get 7-day scores. I want to use the RANKX formula in Power BI to rank the lowest (1) to the highest average score.
This works fine if I look at all, but start to act weirdly when I use a slicer and only look at one or two months for example. The ranking doesn't start with 1 anymore?
I use this formula:
Rank = RANKX(
ALLSELECTED('Score Table'[Person]);CALCULATE(AVERAGE('Score Table'[Score]));;ASC;Dense)
Look at the image attached, please.
Help much appreciated image showing the issue
Can you try this and see if it works?
Rank =
RANKX(
CALCULATETABLE(
VALUES( 'Score Table'[Person] ),
ALLSELECTED( 'Score Table'[Person] )
),
CALCULATE( AVERAGE( 'Score Table'[Score] ) ),
,
ASC,
Dense
)
Let's think about the original code step by step.
It iterates over "Person 1" to "Person 20" and calculates the average score of that person.
Evaluate the average score of the person of current filter context (say "Person 1").
Find the ranking position of "Person 1" in 20 persons.
In the step (1), it includes all Persons from 1 to 20 because there is no Person filter in the visual. Here, it looks there is no scores of Person 15 and 18 in the selected period, so it evaluates to BLANK.
Now, the document of RANKX says,
If expression or value evaluates to BLANK it is treated as a 0 (zero) for all expressions that result in a number, or as an empty text for all text expressions.
The average scores of Person 8 and 15 are BLANK, so RANKX treats it as 0. Now going back to Person 1, her average score was 62.43, and there were two people with average score of 0. Therefore, the rank of Person 1 will be 2.
By wrapping 'Score Table'[Person] with VALUES inside CALCULATETABLE, you can omit persons who has no scores in the selected period.

Trying to figure out how ParallelPeriod works in DAX

I have a simple Power BI table that looks as follows:
I have two tables. A Date table and an Invoice table with a field representing invoice amounts. This is a 1-M relationship on Invoice.InvoiceDate.
The second column is simply a measure for the sum of invoices. The third and fourth columns are measures using ParallelPeriod to sum invoices for 12 months prior and 24 months prior. Even though these numbers are correct, I'm not entirely certain I know what's actually going on.
The measure for the 12-month parallel period looks like this:
Sum Invoice Amount 12 Months Ago =
CALCULATE (
SUM ( FactCustomerTransaction[InvoiceAmountDollars] ),
PARALLELPERIOD ( 'Date'[Date], -12, MONTH )
)
Here is what I think is happening. When the sum is calculated for say 2015-Feb, all values for that month are retrieved in the invoice (many side) table and summed to generate the "Sum Invoice Amount". The sames dates, minus 12 months, in the Date table, are retrieved and the same sum is generated for those range of dates for 'Sum Invoice Amount 12 Months Ago'. And then the same process for 24 months ago.
This works because of the 1-M relationship between Date and Invoice. Is this correct?
For 2015-Feb row, assuming the Year and Month Name column is on your 'Date' table, your filter context is 'Date'[Year and Month Name] = "2015-Feb". This filter corresponds to the dates 2015-02-01 through 2015-02-28 in your 'Date'[Date] column and that filtering propagates across the relationship to return only the rows in FactCustomerTransaction table where InvoiceDate is one of those dates and then sums the amounts corresponding to only those rows.
When you add PARALLELPERIOD, it works the same way except that after matching the dates 2015-02-01 through 2015-02-28 corresponding to 'Date'[Year and Month Name] = "2015-Feb", it shifts those dates back by 12 months and then propagates those shifted dates across the relationship.