Calculation of the relative sales index in Spotfire compared to sales in 1 selected base plan - spotfire

I have got the following data in Spotfire for which I would like to show the relative index of the sales per product compared with a selected base plan.
As shown in the picture above it is possible to calculate the index relative to the previous plan with the following over statement:
100 * (Sum([Sales]) - Sum([Sales]) OVER (PreviousPeriod([Axis.Columns]))) /
Sum([Sales]) OVER (PreviousPeriod([Axis.Columns]))
However this solution has the following three shortcomings:
It compares all sales with the sales in the previous plan instead of one base plan. Changing the OVER statement to use the FirstNode doesn't always work because the data in the real application is imported from the database based upon a query. This results in the value of the FirstNode not always being available.
The ordering of the plans is based upon the string value instead of the plan number (second character in the plan name).
The base plan is not selectable. In the real application a document property "SelectedPlan" is created (containing the selected value in a drop down list).
So how is it possible to calculate the relative sales index compared to the sales of 1 selected base plan?

After some more research we have found a working solution:
100 * (Sum([Sales]) / Sum(If([Plan] = '${SelectedPlan}',[Sales],0)) OVER All([Axis.Columns]))

Related

Cognos: Using rank() across multiple columns to order bar chart

I have some example data like this table:
where the left table is currently the data I have and I want to order by year, company, and product (based on total cost). Currently, the user chooses the year and company on the prompt screen and I am trying to obtain something like a top ten list per year per company based on the total cost per product. I would like my data to sort to the table on the right with keeping track of the billing code area, but not sorting by it. I have been able to write a SQL code that will sort it using a group by, but I cannot add the billing code area. I need the billing code area to display the information in a bar chart.
I have tried using the rank function in Cognos, but I can only do it for one column. I have also tried concatenating the 3 columns together, but no luck with that either. Is there any way to use rank() for 3 columns?
Looks like you have two different tasks:
Calculate top 5
AFAIR you can use rank() like this:
rank([total_cost] for [Country],[Year],[Product])
List all billing area codes. It's not so simple. There is no special function for it (shame on them). So you can write custom query for it using features of you DB or, better, fake concatenation with repeater object or crosstab with master-detail relationship inserted in Billing Area Code field.

DAX Rank by Date

I am Counting on Distinct ID's in a column - this is leading to the sum of the subtotals not equalling the grand total as follows:
What I want to do is rank the Payment Dates in cronological order and select ONLY the highest date to display. In the example above the Grand Total won't change, but the Townville row will not show a Distinct Student Count.
This is a very specific requirement and I'm assuming there's an easy way to do it in DAX - I've tried playing around with both RANKX and MAX but am no closer to solving this.
One last thing - the Rank must be contextual to the Time Filter selected by the user (so if they select 2015 it'd give the second record Rank 1 and the top record wouldn't show. If they select May 2015 it'd give the top record Rank 1 and the second record wouldn't show)
I think this is what you are looking for - I added a calculated column to the PowerPivot model that provides a rank based on the Last Payment Date and the Name of the Student. It will rank the earliest payment for any student as a 1.
The code for the column is as follows:
=RANKX(FILTER(Table1, [Student Name] = EARLIER([Student Name])), [Last Payment Date])
... assuming your table is named "Table1"!
The FILTER is the key that limits the ranking to dates belonging to students with that name only.
Update for Multiple tables
To set up relationships between the tables, go to the "Diagram View" of the model, available in the Home tab of the Power Pivot window.
You can drag fields from one table to the other to create relationships. This will only work if at least one of the fields is unique - it's a good idea to think of the model as a dimensional model, with a tables that acts like a fact and other tables around it that act like dimensions.
From the comment, I would try to get the Payments to act like the fact, and have it link to the Community and Student tables. in this case, you could then have the following code:
=RANKX(FILTER(Table1, Related('Students'[Student Name]) = EARLIER('Students'[Student Name])), [Last Payment Date])
This calculated column would be on your Payments Fact table, and it uses a lookup to a related field.
Note that in this specific case, it would be easier to just run the filter over your Student ID field that is used to lookup the Student name.

DAX to handle cycles of different months

I have 2 tables.
First table: dimensional table to show available units of cars at start of selling cycle and for how long these units will be available.
Second table: to show how many cars were sold on a given month within their "available cycle".
I'd like to compare the "selling behaviour" within each cycle. Thus, I want to display the total initial units available next to the units sold at each stage within the cycle. The second dimension works fine, but not the first one.
This is what I get:
And this the desired output (note rows 4 and 5 for available_units)
I tried the below DAX code without success:
SumAvailableUnits:=CALCULATE(SUM([available_units]),FILTER(ALL(Table1[month_within_cycle]),[month_within_cycle]>=MAX([months_available])))
First, DAX Formatter is your friend. You may like writing unreadable single line measures, but no one else likes reading them.
I've also taken the liberty of cleaning up your table names and adding fully qualified column references. (Ignoring that your dimension isn't a pure dimension, as it holds numeric values that you aggregate in a measure)
SumAvailableUnits :=
CALCULATE (
SUM ( DimCar[available_units] ),
FILTER (
ALL ( FactSale[month_within_cycle] ),
FactSale[month_within_cycle] >= MAX ( DimCar[months_available] )
)
)
And immediately we see a problem. With the fully qualified column references, it is clear that you're trying to filter the lookup table (the one side) by the base table (the many side). In Power Pivot for Excel, we do not have bi-directional relationships (though they're available in Power BI and coming for Excel 2016). Our relationships' filter context only flows from the lookup table to the base table, typically from the dimension to the fact.
Additionally, your DimCar, by holding [available_units] and [months_available] encodes an implicit assumption that a specific [car_id] can only ever refer to a single, unchanging lot. You will never see another row with [car_id] = 1. This strikes me as highly unlikely. Even if it is the case the better solution is a model change.
In general, anything that goes onto a row or column label should come from a dimension, not a fact. Similarly, anything you're aggregating in a measure should live in a fact table. The usual exception is dimension counts - either bare, or as a denominator in a measure. Following these will get you 80% of the way in terms of dimensional modeling. You can see the tables and model diagram I've ended up with in the image below.
Here are the measure definitions
SumAvailableUnits:=SUM( FactAvailability[available_units] )
SumSold:=SUM( FactSale[cars_sold] )
Here are my source tables, my model diagram with relationships, and a pivot table built from these pieces and the measures above. Note the source of [month_within_cycle] in the pivot.
Finally, you might notice that my grand total behaves in a different way than in your original. Since the values are repeated monthly, we get a much larger grand total. If you need to instead end with the sum from the latest month (which it looks like you have in your sample), you can use an alternate measure, provided below. I don't understand why this would be your desired grand total, but you can achieve it fairly easily. Personally, I'd probably blank the measure at the grand total level.
SumAvailableUnits - GrandTotal:=
SUMX(
TOPN(
1
,FactAvailability
,FactAvailability[month_within_cycle]
,0
)
,FactAvailability[available_units]
)
This uses SUMX() to step through the table provided, defined by TOPN(). TOPN() returns the first row (in this case) in FactAvailability, including ties, after sorting by [month_within_cycle], out of all rows available in the filter context. In the context of a specific month, you get all the rows associated with that month - identical to the simple sum. In the grand total context, you get the rows associated with the last month.
SUMX() iterates over that table and accumulates the values of [available_units] in a sum.

SSAS Cube Calculation to summarise another measure at a coarser level

I have run into performance problems with MDX measure calculations for a summary report, using SQL Server 2008 R2.
I have a Person dimension, and a related fact table containing multiple records per person. (Qualifications)
Eg [Measures].[Other Qual Count] would give me the number of qualifications of a certain type.
Each person could have multiple, so [Measures].[Other Qual Count] > 1 for one person.
However on my summary report I would like to indicate this as 1 per person only. (To indicate the number of persons with Other qualifications.)
The summary report rolls up the values against some other dimensions including an unknown Region hierarchy (it can be one of 3 hierarchies).
I have done this as follows:
MEMBER [Measures].[Other Count2]
AS
SUM(
EXISTING [Person].[Staff Code].[Staff Code].Members,
IIF([Measures].[Other Count] > 0, 1, NULL)
)
However, I have to create several more derived measures - deriving from each other, and all at Person level to avoid unwanted multiple counts. The query slows down from <1 second to 1min+ (my goal is <3s).
The reason for all the derivations is a lot of logic to determine within which one of 6 mutually exclusive column a person will be reported in.
I have also tried to create a Cube Calculation, but this gives me the same value as [Other Count].
SCOPE (({[Person].[Staff Code].[Staff Code].MEMBERS}, [Measures].[Has Other Qual]));
THIS = ([Person].[Staff Code].[Staff Code], [Measures].[Has Other Qual]).Count;
END SCOPE;
Is there a better MDX/Cube calculation that can be used, or any suggestions on improving performance?
This is unfortunately my first time working with MDX and ran into this problem close to a deadline, so I am trying to make this work if possible without changes to the cube.
I have resolved the issue by changing the cube, which was simpler than expected.
On the Data Source View, I created a named query which summarizes the existing fact table at Person level. I also derive all the columns which I will need on my reports.
Treating this named query as a separate fact table, I added a measure group for it and that resolved all my problems.

Get the average monthly value from 2 SP List columns and display in new column

I need to calculate the average value for each month. Currently I have 2 columns "DATE" (date value e.g 01/01/2010) and AccOpen (number value). So for all dates within January I need to return the average value of all numbers contained in the corresponding AccOpen rows for January dates.
Is it possible to use the CALCULATED option and input a FORMULA that will return the average for all itmes within each months period (when adding a column to the list ?
DATE ACCOPEN AVERAGE
01/01/2010 2 2
02/01/2010 2
03/01/2010 2
04/01/2010 2
01/02/2010 2 2
02/02/2010 2
03/02/2010 2
04/02/2010 2
You're not going to be able to do this OOTB without writing event receiver code (or other custom code running in a batch mode).
To get you started
MSDN - How to: Create an Event Handler Feature
Event Handlers : Everything you need to know...
This will need to hook into the list item update and then consolidate your list into a separate summary list with the calculations you need.
The brute force approach would be to run the calculation afresh for every item in the group when an item is inserted/updated.
A smarter approach would be to just update the delta (the difference between the old and the new record) which is easier to do if you store components of the calculation - so in your case
Month - NumRecords - TotalValue
and work out the Average on the fly (as its easy to delta the NumRecords/TotalValue but impossible to apply it directly to the average)
One 3rd party web part which may fit your need is PivotPoint - it allows you to do things like sum/count/avg over groups like Month & Year (disclaimer - I work for the company)
It is not possible to query anything other than the current item when creating a formula field.
The only way to do this is to create custom code either within an event handler for the list or external code that processes items in the list and updates a "average" field when required.
Create a calculated field to give you the year and month, for example: 2011-07. Then modify your list view to group on the calculated field. When editing your view, there is also an option to display totals, I believe you can set this to average for your AccOpen column. If you're not interested in the details, you can choose to collapse all groups by default.

Resources