I have a calculated measure that works, but shows #VALUE! in Grand Total
in Browser in SSAS. The Current Forecast for months1-3 have no values and
greater than current month Qty Shipped contains no values when I drop those
measures in Browser to help debug.
case
when [month part] >= [Current Month] then [Measures].[Current Forecast]
when [month part] < [Current Month] then [Measures].[Qty Shipped]
else 0
end
Any help to what whats wrong
Use ISEMPTY() function
Syntax
IIF(ISEMPTY(A) AND ISEMPTY(B), NULL, IIF(A=0 OR B = 0, 0, A/B)) i.e
IIF(
ISEMPTY([MEASURES].[A]) AND ISEMPTY([MEASURES].[B]), NULL,
IIF([MEASURES].[A] = 0 OR [MEASURES].[B]=0 , 0, [MEASURES].[A]/[MEASURES]. [B])
)
Related
I have my query:
SELECT [Shipment Date], [Amount] as [Running Costs], Sum([Amount]) OVER
(ORDER BY [Shipment Date]) as [Total Running Costs]
FROM...
This gets me 3 columns:
Shipment Date | Running Costs | Total Running Costs
I would like to add a fourth column to this query which has the same value for all rows, and the same number of rows as my original query results.
I know you could add for example '999'as Something to the search results, but how can I do the same for a sum of another column (example: Imagine the total sum of the a column in another table is 1500, and I want to have 1500 for all rows in the fourth column. Something like select sum(column_name)?
The database engine is MSSQL.
You can use a nested query
SELECT [Shipment Date], [Amount] as [Running Costs], [Total Running Costs], SUM([Total Running Costs] OVER ())
FROM
(
SELECT [Shipment Date], [Amount] as [Running Costs], Sum([Amount]) OVER
(ORDER BY [Shipment Date]) as [Total Running Costs]
FROM...
)
Nested window function should also work
SUM(SUM([Running costs]) OVER (ORDER BY [Shipment Date])) OVER ()
Here is a snip of my cube's dimension usage:
In "TD Measures" I have
[A] "Billable Client Hours Current".
In "Personnel Measures" I have
[B] "FTE Count" (an employee's amount they are working like .5 for
people who work 20 hours per week)
[C] "Forecast FY End" Forecast for the end of the fiscal year
[D] "Forecast FYTD" Forecast for the current period to date in the fiscal year.
The calculation I need to do at a leaf level is:
[A][B][C]/[D]
The issue is that [A] has more dimensionality that [B], [C], and [D].
So If this is my data:
The calc I need to do is:
((15*.05)+(5*1)) //sum of hours in a period multiplied by that month's FTE
X 2000/300 //last child of FCFYE divided by last child of FCFYTD in the currently selected set.
This calc is likely to change a little over the next week or two, but this is the main concept of what they are looking to do. Any help in writing the MDX for this to create a calculated member in my cube is greatly appreciated. Sorry if I've left out any key info--I'm quite the MDX noob.
Through digging through Chris Webb's and Mosha's posts as well as working with some guys on the MSDN forums I have worked out a solution to this below. Ultimately, I worked out with the business that we didn't need to interrogate the underlying rows to discern if they were active or not since the addition of the root functionality eliminated the need as long as they filtered on it from DimMiscellaneous. But for the sake of helping someone with a similar problem here is the full MDX below.
//Only evaluate if they are active
CREATE HIDDEN UtilizedFTESummator;
[Measures].[UtilizedFTESummator] = Iif([Measures].[Is Active For Utilization Value] > 0,[Measures].[Period FTE],NULL);
NON_EMPTY_BEHAVIOR([Measures].[UtilizedFTESummator]) = [Measures].[Is Active For Utilization Value];
//only include this measure if the underlying employee has values in their underlying data for active in utilization
CREATE MEMBER CURRENTCUBE.[Measures].[FTE Active Utilization]
AS
SUM
(
EXISTING [Historical Personnel].[Employee Id].[Employee Id],
[Measures].[UtilizedFTESummator]
),VISIBLE=0;
//Show weighted FTE by workdays
CREATE MEMBER CURRENTCUBE.[Measures].[FTE MTD Active Utilization]
AS SUM
(
DESCENDANTS([Historical Personnel].[Employee Id].CURRENTMEMBER,[Historical Personnel].[Employee Id].[Employee Id]),
(
DIVIDE
(
SUM
(
DESCENDANTS([Period].[Fiscal Period].CURRENTMEMBER,[Period].[Fiscal Period].[Fiscal Period]),
[Measures].[FTE Active Utilization]*[Measures].[Work Days In Month]
)
,SUM(ROOT([Historical Personnel].[employee id].currentmember),[Measures].[Work Days In Month])
,0
)
)
);
//Use Weighted FTE for calculating the weighted value for each person (all periods aggregated)
//Forecast Billable End Of Year has default aggregation of last child
CREATE MEMBER CURRENTCUBE.[Measures].[Annualized CBH Projected]
AS DIVIDE
(
SUM
(
DESCENDANTS([Historical Personnel].[Employee Id].CURRENTMEMBER,[Historical Personnel].[Employee Id].[Employee Id]),
[Measures].[Billable Client Hours Current] *
(
DIVIDE
(
[Measures].[Forecast Billable End Of Year]
,
[Measures].[Forecast Billable FTE]
,0
)
)
*[Measures].[FTE MTD Active Utilization]
)
,[Measures].[FTE MTD Active Utilization]
,0
);
Simplified answer with the users filtering on the Is Active For Utilization flag is as follows:
//Weight FTE by employee calculating FTE * workdays for each period and then dividing by the sum of days irrespective of filters on historical personnel or miscellaneous
CREATE MEMBER CURRENTCUBE.[Measures].[FTE MTD]
AS SUM
(
DESCENDANTS([Historical Personnel].[Employee Id].CURRENTMEMBER,[Historical Personnel].[Employee Id].[Employee Id]),
(
DIVIDE
(
SUM
(
DESCENDANTS([Period].[Fiscal Period].CURRENTMEMBER,[Period].[Fiscal Period].[Fiscal Period]),[Measures].[Period FTE]*[Measures].[Work Days In Month]
)
,
SUM((ROOT([Historical Personnel].[employee id].currentmember),ROOT([Miscellaneous]),[Measures].[Work Days In Month]))
,0
)
)
);
//Weight by FTE with default agg for Forecast EOY being last child.
CREATE MEMBER CURRENTCUBE.[Measures].[Annualized CBH Projected]
AS DIVIDE
(
SUM
(
DESCENDANTS([Historical Personnel].[Employee Id].CURRENTMEMBER,[Historical Personnel].[Employee Id].[Employee Id]),
[Measures].[Billable Client Hours Current] *
(
DIVIDE
(
[Measures].[Forecast Billable End Of Year]
,
[Measures].[Forecast Billable FTE]
,0
)
)
*[Measures].[FTE MTD]
)
,[Measures].[FTE MTD]
,0
);
How do I create a DAX measure that will show me the First Receipt Date where the Receipt Balance is greater than or equal to the Payment Balance?
For example, for Jun, I want the [Payment Receipt Date Avg] measure to show as Jan because the Receipt Balance is 10 which is greater than the Payment Balance of 8.
For Aug, it would show as Feb because that is the first date where the Receipt Balance is at least the Payment Balance of 13.
Desired Result:
Data Model
Table: Po Receipt
Table: Payment
Attempted Solution
I already have the below measures defined:
Receipt Balance:
=CALCULATE
(
SUM(PoReceipt[Quantity Received]),
FILTER
(
ALL ( PaymentDates ),
PaymentDates[Payment_FullDate] <= MAX ( PaymentDates[Payment_FullDate] )
)
)
Payment Balance:
=CALCULATE
(
SUM(Payment[Payment Amount]),
FILTER
(
ALL ( PaymentDates ),
PaymentDates[Payment_FullDate] <= MAX ( PaymentDates[Payment_FullDate] )
)
)
Create calculated columns to get the first date which has a net receipt running total (i.e. receipts less payments running total) greater than the payment amount in the current row context. The calculated columns will need to do the following:
Return the running total of [Payment Amount] for each [PO Num]. The EARLIER function is used so that for each row in the outer context, you sum all rows in the inner context where the inner row has a [Payment Date] less than or equal to the outer row, and the inner row's [Po Num] is equal to that of the outer row.
Return a summary table based on the PoReceipt table, which has an extended column "Receipt Balance Calc". The extended column calculates the running total of the PoReceipt[Quantity Received] similar to step 1. The summary table is grouped by the columns [Po Num] and [Receipt Date] to avoid performing the same calculation more than once (since there are multiple rows with the same [Po Num] due to the [Receipt Num] column).
Filter the result to only include rows where the Receipt Balance is greater than or equal to the Payment Balance.
See DAX code for calculated columns:
Payment[Payment Balance Calc]
=CALCULATE (
SUM ( Payment[Payment Amount] ),
FILTER (
Payment,
Payment[Payment Date] <= EARLIER ( Payment[Payment Date] )
&& Payment[Po Num] = EARLIER ( Payment[Po Num] )
)
)
Payment[Payment Receipt Date]
=CALCULATE (
MIN ( PoReceipt[Receipt Date] ),
ALL ( PaymentDates ),
FILTER (
ADDCOLUMNS (
SUMMARIZE (
PoReceipt,
PoReceipt[Po Num],
PoReceipt[Receipt Date]
),
"Receipt Balance Calc",
CALCULATE (
SUM ( PoReceipt[Quantity Received] ),
FILTER (
PoReceipt,
PoReceipt[Receipt Date] <= EARLIER ( PoReceipt[Receipt Date] )
&& PoReceipt[Po Num] = EARLIER ( PoReceipt[Po Num] )
)
)
),
[Receipt Balance Calc] >= EARLIER ( Payment[Payment Balance Calc] )
)
)
Finally, create the below measure to calculate the weighted average of the receipt dates:
Payment Receipt Date Avg:=
SUMX (
Payment,
Payment[Payment Amount] * Payment[Payment Receipt Date]
/ SUM ( Payment[Payment Amount] )
)
I am trying to create a calculated member which should returns the averages orders per week per person.
Below is the screen shot where the client will be looking to forecast the work load. Staff may not work all the days in a week.
The calculation will be : No of Orders / No of scheduled days in that week.
It would not be very hard to calculate this if the week name is in the same hierarchy of the date, but in this case it is not in hierarchy but just member of the dimension.
This is the MDX I've tried:
Avg ( Descendants
( [Date Planned].[Date Planned].CurrentMember, [Date Planned].[Date Planned].[Date Planned] ),
[Measures].[Orders Qty] )
It would be much easier when you have week and day added into the hierarchy, but if you don't have possibility to have this added, there is different non elegant solution.
If you would assume that this member will always be used with Week on rows your member calculation would be as follow:
This will work correctly only with weeks on rows - so I would recommend to extend your Calendar hierarchy by week and day and then we can have a chat about much more elegant solution.
Try using this:
WITH MEMBER [Measures].[avg_week] AS
Avg ( EXISTING { [Date Planned].[Week Of Year].[Week Of Year] },
[Measures].[Orders Qty] )
SELECT [Measures].[avg_week] ON COLUMNS,
NON EMPTY
{ [Person].[PersonName].[PersonName] * [Date Planned].[Week Of Year].[Week Of Year] } ON ROWS
FROM [Your cube]
Let me know if this can help you.
Maybe something like the following:
WITH
MEMBER [Measures].[PlannedDayCnt] AS
Count
(
Exists
(
(EXISTING
[Date Planned].[Date Planned].[Date Planned].MEMBERS)
,[Date Planned].[Week Of Year].currentmember
)
)
MEMBER [Measures].[Averge Orders] AS
[Measures].[Orders Qty] / [Measures].[PlannedDayCnt]
SELECT
{
[Measures].[Orders Qty]
,[Measures].[PlannedDayCnt]
,[Measures].[Averge Orders]
} ON 0
,
[Person].[PersonName].[PersonName]
* [Date Planned].[Week Of Year].[Week Of Year] ON 1
FROM [aCube];
I'd like to test but unsure how to model your scenario in the AdvWrks cube.
I would first want to see how many "dates" belong to the week. That would be easy as it would be those days when Orders were placed for that person that week.
NonEmpty
(
[Date Planned].[Date Planned].[Date Planned].MEMBERS,
(
[Date Planned].[Week Of Year].currentmember,
[Person].[PersonName].currentmember,
[Measures].[Orders Qty]
)
)
Now that you have the requisite dates for the "current" week and the "current" person, you would need to calculate the average order quantity for these set of dates. It would look like this:
AVG
(
NonEmpty
(
[Date Planned].[Date Planned].[Date Planned].MEMBERS,
(
[Date Planned].[Week Of Year].currentmember,
[Person].[PersonName].currentmember,
[Measures].[Orders Qty]
)
)
, [Measures].[Orders Qty]
)
Your final construct would need to be:
WITH MEMBER Measures.AverageOrderPerDay AS
AVG
(
NonEmpty
(
[Date Planned].[Date Planned].[Date Planned].MEMBERS,
(
[Date Planned].[Week Of Year].currentmember,
[Person].[PersonName].currentmember,
[Measures].[Orders Qty]
)
)
, [Measures].[Orders Qty]
)
SELECT
{
[Measures].AverageOrderPerDay,
[Measures].[Orders Qty]
}
ON 0,
[Person].[PersonName].[PersonName].MEMBERS
* [Date Planned].[Week Of Year].[Week Of Year].MEMBERS ON 1
FROM [YourCube]
Is there a way for me to view the first and/or last leaf value in a level of a hierarchy?
I am trying to create a calculation dimension in SSAS which will include, for example, a year to date calculation which I would prefer not to display for dates in the future.
I've worked out how to make that happen at the lowest level (date), but am getting errors ath te aggregation levels when trying to implement the technique.
To help me accomplish what I want I've included a [Date In Past] member in my dimension, which contains a 0 if the date is in the past, and a if it is not.
For example this query, which returns calculations by date:
with member [Measures].[Year To Date] as
Sum(
{ IIF(strtovalue(
[Time Order Date].[Date In Past].Currentmember.membervalue
) = 0, null, [Measures].[Product Rev (with ship, no disc)]
) } *
PeriodsToDate(
[Time Order Date].[Fiscal Date].[Fiscal Year Name],
[Time Order Date].[Fiscal Date].CurrentMember
)
)
select
{[Measures].[Product Rev (with ship, no disc)],
[Measures].[Year To Date]} on 0,
[Time Order Date].[Date].Children on 1
from [Sales Analysis]
returns nulls in the [Year to Date] measure for all dates in the future.
This query, which returns calculations by the week:
with member [Measures].[Year To Date] as
Sum(
{ IIF(strtovalue(
[Time Order Date].[Date In Past].Currentmember.membervalue
) = 0, null, [Measures].[Product Rev (with ship, no disc)]
) } *
PeriodsToDate(
[Time Order Date].[Fiscal Date].[Fiscal Year Name],
[Time Order Date].[Fiscal Date].CurrentMember
)
)
select
{[Measures].[Product Rev (with ship, no disc)],
[Measures].[Year To Date]} on 0,
[Time Order Date].[Fiscal Week Name].Children on 1
from [Sales Analysis]
returns errors for all of the [Year To Date] values, I assume because there are more than one member in the week.
I would like to compare it with the last day of the week. How can I do that?
Thanks, --sw
To answer your question literally: Yes, you can get the first or last member of a set, and hence of a level, using the Head and Tail methods. Just note that these return a one-element set, hence you would often use Tail(something).Item(0).Item(0) to get a member.
However, as I understand your question, what you really need is to know if in the currently context, the member [Time Order Date].[Date In Past].[a] exists.
In that case, I would use
with member [Measures].[Year To Date] as
IIf(Intersect(EXISTING [Time Order Date].[Date In Past].[Date In Past].Members,
{[Time Order Date].[Date In Past].[a]}
).Count = 1,
NULL,
Sum(PeriodsToDate([Time Order Date].[Fiscal Date].[Fiscal Year Name],
[Time Order Date].[Fiscal Date].CurrentMember
)
[Measures].[Product Rev (with ship, no disc)]
)
)
select
{[Measures].[Product Rev (with ship, no disc)],
[Measures].[Year To Date]} on 0,
[Time Order Date].[Fiscal Week Name].Children on 1
from [Sales Analysis]
EXISTING gets the set of all Date In Past members that exist in the current context. And the intersection of that with the one-element set of member a has either 1 element (if a is member of the first set), or 0 elements (in case a is not contained in the set), which explains the condition for the IIf.