I was trying to get a worst performing product group for a selected date, using bottom count. My aim is to return the amount and not the dimension name. But the query is returning the bottom count based on the default date in the cube and not form the select query. Is there a way to pass the current date into the bottomcount? Below is the sample query which i was using:
with
member worst as
([Measures].[Amount])
set worstgrp as
BOTTOMCOUNT([Product].[Product].Members ,1 , [Measures].[worst])
member worstamount as
sum([worstgrp],[Measures].[Amount])
select
{[worstamount]} on 0,
([date].[date].[month-day].[18 Jul 2014]) on 1
from
[Full Details]
We can have multi select on date. And to be exact I am trying to create a calculated member in the cube and use that cube for an ad hoc report usinfg excel. So I guess we cannot pu the date in where clause, but only in select clause.
Just define your set as follows:
set worstgrp as BOTTOMCOUNT([Product].[Product].Members ,1 ,
sum(EXISTING [date].[date].Members, [Measures].[worst]))
Related
In Excel connected to SSAS, I am trying to build a pivot table and add a custom Measure Calculation using "OLAP Tools" and/or "OLAP Pivot Table Exensions". I am trying to add a calculation that is really simple in my mind, but I cannot get it to work. The calc I need is:
GOAL: A record count of the [Items] dimension records grouped by any of the
[Items] dimension fields.
In particular I am trying to group by [Items].[Items Groups] and [Items].[Item]. Item is the lowest grain, so the count should return value "1". I have created a couple calculations that are kind of in the ballpark (see below). But the calcs don't appears to be working as desired.
What I have tried:
Attempt #1 -- [Measures].[Items Count (With net amount values)]
DISTINCTCOUNT( {[Items].[Item].MEMBERS} )
The calc 'Items Count (With net amount values)' appears to be
returning a decent count value, but it appears it only counts the Item
if there are transnational records found (not sure why). Also, when
at the lowest grain level the calc returns that value for the parent
group, not the dimension level selected on the rows.
Attempt #2 -- [Measures].[Items Count (All)]
[Items].[Item].[Item].Count
This calc returns the TOTAL item count for the entire dimension
regardless of the dimension level placed on the rows.
Attempt #3 -- [Measures].[Items Count]
COUNT ( { [Items].[Item].MEMBERS}, EXCLUDEEMPTY)
This calc freezes up Excel and I have to quit Excel. No idea why. I have seen this sytnax recommended on a few different sites.
Screenshot:
Help please? This seems really simple, but I am not very skilled with MDX. In DAX and SSAS TABULAR this would be very simple expression. But I'm struggling to count the rows with MDX in SSAS MD.
The "Outside Purchased Beef" group has 18 items with transactions, but 41 items in total. I do not know how to calculate the "41" value.
SSAS Excel-CalcMeasure-CountRows.png
Take a look at the following samples on AdventureWorks.
with member [Measures].[CountTest]
as
count(existing [Product].[Subcategory].members - [Product].[Subcategory].[All])
select
{
[Measures].[Internet Sales Amount],[Measures].[CountTest]
}
on columns,
{
([Product].[Category].[Category]
,[Product].[Subcategory].[Subcategory] -- comment this line for the second result
)
}
on rows
from [Adventure Works]
Now comment the indicated line for the parent view.
I have a situation where I kind of need a many-to-many join - which I know isn't possible.
I have one fact table and two dimension tables.
The fact table contains account numbers (as in GL accounts) and amounts. Plus a date field, so the account numbers are not unique.
The first dimension table has just one column listing the reports that can be created by combining the accounts in different ways.
The second dimension table could be called a "roll-up" table. It has 3 columns: report, account, and a line item description field. The latter defines which line on the respective report that the account should be mapped to.
So I want to have a pivot table that has the line item description in the row area and the amount in the values area. With a mechanism for the user to specify which report they want to view. But the join on the account field between the roll-up table and the fact table is many-to-many. If the roll-up table were somehow filtered based on the specific report that the user has selected, THEN it would become one-to-many. Hence the "dynamic" joins in my title.
I've been trying to come up with a connecting table of some kind, but without any luck so far. If anybody has any suggestions/pointers, that would be much appreciated.
I figured out a way to do it using a DAX formula that calculates the field to be placed in the Values area. It uses FILTER and CROSSJOIN combinations to effect the dynamic joins. Note that in order to use a CROSSJOIN I added prefix letters to a couple of the field names (to make them unique). Also, I made it that the Report table (the first dimension table I described) has only one row - containing the report that the user wishes to view.
The DAX formula is as follows:
SUMX (
FILTER (
CROSSJOIN (
fBalances,
FILTER (
CROSSJOIN (
dRollUp,
dReport
), dRollup[Report] = dReport[uReport]
)
), fBalances[fAccount] = dRollUp[Account]
), fBalances[Amount]
)
Subsequent update: I moved it into Power BI where I added a parameter (called myReport) for the user to specify the report. Consequently I deleted the dReport table.
So the Power BI DAX formula becomes:
SUMX (
FILTER (
CROSSJOIN (
fBalances,
FILTER (
CROSSJOIN (
dRollUp,
myReport
), dRollup[Report] = FIRSTNONBLANK ( myReport[myReport], TRUE() )
)
), fBalances[fAccount] = dRollUp[Account]
), fBalances[Amount]
)
I would like to calculate the sum of open positions in a receivables account. The entries in the accounting system provide three relevant columns in the source table to that end:
booking date
due (=pay) date
amount due
I would like to have a measure that I can use for a graph, showing the total of all open positions on each day.
An open position is an amount booked with a booking date before "today" and with a due date after "today".
I tried the following approach in my Power Pivot model (with three calendar tables):
booking date related to "calendar table 1"
due date related to "calendar table 2"
Date columns of "calendar table 1" and "calendar table 2" related to a third "calendar table main"
For that formula I am getting an error message:
Hm, not sufficiently proficient in PowerPivot to solve this problem.
SumAmt:=
SUM( Source_Table[Amount] )
OpenPositions:=
CALCULATE(
[SumAmt]
;FILTER(
VALUES( Source_Table[Booking_Date] )
;Source_Table[Booking_Date] < MAX( Calendar_Main[Calendar_Date] )
)
;FILTER(
VALUES( Source_Table[Due_Date] )
;Source_Table[Due_Date] > MAX( Calendar_Main[Calendar_Date] )
)
)
Your error is pretty self-explanatory. If you use a direct column reference in CALCULATE() you can only reference a single column. You are referencing two, Calendar_Main[Calendar_Date] and either Source_Data[Booking_Date] or Source_Data[Due_Date]. This is simply not allowed, so it throws the error.
The workaround is simply to wrap complex filtering logic in table expressions and use those as arguments to CALCULATE(). Pretty much, unless you are hard-coding a literal predicate for a single column, you should be using some sort of table expression, like FILTER(), as your arguments to CALCULATE().
What we do is call FILTER() twice to check the dates. We use MAX()s because we cannot perform comparisons between column references, we need to perform inequality comparisons between scalars.
Since we're FILTER()ing over Source_Data[Booking_Date] and Source_Data[Due_Date], the references to these are evaluated in row context and refer to the value of the current row in FILTER()'s iteration. The reference to Calendar_Main[Calendar_Date] is just a column reference, so we wrap it in MAX() to get a scalar value for our inequality. The MAX() refers to the current filter context coming in from the pivot table, which would be the current row label or column label.
If you aggregate to the month level, this will give you essentially the closing balance, since we're using MAX()s. At the month level the value will be identical to that on the last date of the month.
Finally, with the inequalities you've set up, you're ignoring anything opened on the current day or due on the current day. I'd expect you want [Booking_Date] <= [Calendar_Date] and [Due_Date] > [Calendar_Date].
Since SSRS doesn't allow filters on aggregates, I found some code which helped me come up with the below query. However, when I run it I get:
Each GROUP BY expression must contain at least one column that is not an outer reference
I have searched everywhere but can't find how to fix this. I've even removed the two extra tables from the query so there were no joins at all. I need to not return any order where the total of the lines on the order is less than $500 and greater than 0.
SELECT
tdsls041_sales_order_lines.company,
tdsls041_sales_order_lines.order_number,
tdsls041_sales_order_lines.amount,
tdsls041_sales_order_lines.item,
tdsls041_sales_order_lines.container
FROM
tdsls041_sales_order_lines AS tdsls041_sales_order_lines
WHERE
(tdsls041_sales_order_lines.company = 610) AND
(tdsls041_sales_order_lines.order_number IN
(SELECT
tdsls041_sales_order_lines.order_number
FROM
tdsls041_sales_order_lines AS tdsls041_sales_order_lines_1
GROUP BY
tdsls041_sales_order_lines.order_number
HAVING
(SUM(tdsls041_sales_order_lines.amount) <= 500) OR
SUM(tdsls041_sales_order_lines.amount) > 0))
The issue that SQL Server is complaining about is that the Grouping wants an aggregate function in the SELECT statement. Unfortunately, you want to use IN which you need a list of Order Numbers.
You just need to add an aggregate function to your subquery and then add another layer to select just the Order Numbers from that.
SELECT T1.company, T1.order_number, T1.amount, T1.item, T1.container
FROM tdsls041_sales_order_lines AS T1
WHERE (T1.company = 610) AND (T1.order_number IN
(SELECT order_number FROM
(SELECT TSOL.order_number, SUM(TSOL.amount) AS TTL
FROM tdsls041_sales_order_lines AS TSOL
GROUP BY TSOL.order_number
HAVING (SUM(TSOL.amount) <= 500) OR
SUM(TSOL.amount) > 0) AS T2) )
You can filter on aggreagates in Chart and Tables. You have to put the aggregate filter on your GROUP instead of on the table itself (Group Properties->Filters tab).
I have a PowerPivot Data Model in Excel 2013. There are several measures that I have grouped into a named set using MDX - something like this:
{[Measures].[Sum of Value1],
[Measures].[Sum of Value2],
[Measures].[Sum of Value3]}
By using this named Set, I can place multiple measures on the rows or columns of an Excel PivotTable in a single action. My question is, is there any way using MDX (or DAX in the PowerPivot screen when working with the individual measures) to filter out or hide the entire set based on a single measure value (whether that measure is included in the set or not)? Preferably, I'm looking for a way to do this without including another member in the set (I.e. Not a measure).
Ror example, if the Sum of Value3 in the above example was zero, I'd want the entire set to be hidden from the pivot table.
I know I could edit the DAX in the Data Model to return BLANK() for each measure included in the set based on the value of another measure, but there may be times I want to show those measures in all cases. This would require writing at least 2 measures for every one I have now which I don't like the thought of doing.
UPDATE:
Sourav's answer looks great, but unfortunately won't work in my particular scenario, I believe, because I'm using the "Create Set using MDX" function (under the Manage Sets option in the Fields, Items, & Sets ribbon menu) within Excel. It will only let me write the MDX as:
IIF([Measures].[Sum of Value3]=0,
{},
{[Measures].[Sum of Value1],[Measures].[Sum of Value2],[Measures].[Sum of Value3]})
And once I add that new set to the PivotTable, it will still display all 3 measures for any members where [Sum of Value3] is 0.
I think I'm going to have to find an approach using DAX and the Excel Data Model measures.
UPDATE 2:
Below is a screenshot to help illustrate. Keep in mind the data source in my example is not an external cube, it's simply an Excel file linked in the Data Model against which MDX queries (with limitations?) can be run. In this example, I would like the set to return only Rows A and C because Sum of Value3 is not zero. However, as you can see, all rows are being returned. Thanks!
You can't choose to hide/unhide members/sets on the fly. Instead, you can use IIF to conditionally return an empty set
WITH SET MyNamedSet AS
IIF([Measures].[Sum of Value3] = 0,
{},
{[Measures].[Sum of Value1],[Measures].[Sum of Value2], [Measures].[Sum of Value3]}
Working example in AdventureWorks for #whytheq(DISCLAIMER - Cube was created by me for testing purposes)
with set abc as
iif([Measures].[Fact Internet Sales Count]>34229,
{
[Measures].[Fact Internet Sales Count],
[Measures].[Extended Amount - Fact Internet Sales]
},
{}
)
SELECT
abc
on 0
from [AdventureWorksDW]
where [Due Date].[Year].&[2004]
As you can see, the scope IS changing the results.
An alternative would be to create a dummy measure that returns null or 1 depending on your [Measures].[Sum of Value3]. Then multiply all other target measures by this dummy measure.
Here is an example of you scenario in AdvWrks:
SELECT
[Product].[Product Categories].[Category].[Components] ON 0
,{
[Measures].[Internet Sales Amount]
,[Measures].[Sales Amount]
,[Measures].[Standard Product Cost]
,[Measures].[Total Product Cost]
} ON 1
FROM [Adventure Works];
Returns this:
Adding the dummy measure and amending the other measures:
WITH
MEMBER [Measures].[isItZero] AS
IIF
(
[Measures].[Internet Sales Amount] = 0
,null
,1
)
MEMBER [Measures].[Sales Amount NEW] AS
[Measures].[Sales Amount] * [Measures].[isItZero]
MEMBER [Measures].[Standard Product Cost NEW] AS
[Measures].[Standard Product Cost] * [Measures].[isItZero]
MEMBER [Measures].[Total Product Cost NEW] AS
[Measures].[Total Product Cost] * [Measures].[isItZero]
SELECT
NON EMPTY //<<<<this is required
{
[Measures].[Internet Sales Amount]
,[Measures].[Sales Amount NEW]
,[Measures].[Standard Product Cost NEW]
,[Measures].[Total Product Cost NEW]
} ON 0
,{} ON 1
FROM [Adventure Works]
WHERE
[Product].[Product Categories].[Category].[Components];
Now this returns:
EDIT
According to your latest edit please just try this (I'm assuming you're using Excel 2013):
Create two new measures to replace two of the existing ones:
Name: "Sum of Value1 NEW"
Definition:
IIF
(
[Measures].[Sum of Value3] = 0
,null
,[Measures].[Sum of Value1]
)
Name: "Sum of Value2 NEW"
Definition:
IIF
(
[Measures].[Sum of Value3] = 0
,null
,[Measures].[Sum of Value2]
)
Now use only these three measures in your pivot and just use the ID dimension in a normal way on rows i.e. do not use the custom set you have already tried.
[Measures].[Sum of Value1 NEW]
[Measures].[Sum of Value2 NEW]
[Measures].[Sum of Value3]
Has ID B should now disappear?