Check if an item exists in MDX named set - ssas

I want to create a named set for two football teams. I'm not exactly sure what the syntax is, but what I have thus far is:
EXISTS(
[Team].[Team],
{[Team].[Team].&[BAL], [Team].[Team].&[DEN]}
)
In other words, I want to create a Named set if the team is named "BAL" or "DEN". What would be the proper way to write this expresion?
The following query syntax works for me, but I'd like to translate this into "creating a named set" in BIDS:
WITH SET[FavoriteTeams] AS{
[Team].[Team].&[DEN],
[Team].[Team].&[BAL]
}
SELECT
[Measures].[Net Wins] on 0,
[FavoriteTeams] on 1
FROM [NFL]
It seems perhaps it is as simple as just typing that in manually to the expression?

Sets are an important concept in MDX. A set is a collection of members from the same dimension and hierarchy. The hierarchy can be an attribute hierarchy or a user-defined hierarchy.
set = {membre1,member 2 ..}
the simpler the set expression the better it is.
So you should use the second expression
{
[Team].[Team].&[DEN],
[Team].[Team].&[BAL]
}
In your case no need to use the exists function since the members are defined.
we use exists in some setuations like we want to get all the cities of a specific region.
EXISTS([City].[City], [region].[region].[Region].&[1])
Visit : Microsoft.doc

Related

undefined method `and' for #<Arel::Attributes::Attribute

I'm having an issue getting a query to work.
I'm essentially trying to write something like the following SQL, with the literal 5 replaced with a variable:
SELECT *
FROM "my_table"
WHERE 5 BETWEEN "my_table"."minimum" AND "my_table"."maximum"
This is what I have at the moment:
MyModel.where(
Arel::Nodes::Between.new(
my_variable, (MyModel.arel_table[:minimum]).and(MyModel.arel_table[:maximum])
)
)
Please ignore the way I am using arel_table, the actual query has multiple joins and is more complex, but this is the most minimum reproducible example I have to demonstrate the problem.
The error, as in the subject of the question is as follows:
undefined method `and' for #<Arel::Attributes::Attribute:0x00007f55e15514f8>
and method is for Arel::Nodes::Node i.e. MyModel.arel_attribute[:name].eq(Arel::Nodes::Quoted.new('engineersmnky')) This is an Arel::Nodes::Equality and you can chain with and.
That being said you can construct an Arel::Nodes::And for yourself via
Arel::Nodes::And.new([left,right])
Then we can pass this to the Between class like so
Arel::Nodes::Between.new(
Arel::Nodes::Quoted.new(my_variable),
Arel::Nodes::And.new([
MyModel.arel_table[:minimum],
MyModel.arel_table[:maximum]])
)
The Arel::Nodes::Quoted (also: Arel::Nodes.build_quoted(arg)) is not needed in your case since your my_variable is an Integer which can be visited and will be treated as an Arel::Nodes::SqlLiteral but I find it best to let arel decide how to handle the quoting in case your my_variable ends up being some other un-visitable Object
There are other ways to create a Between and other ways to create an And depending on what objects you are dealing with.
between is a Arel::Predication and these predications are available to Arel::Nodes::Attribute objects e.g.
MyModel.arel_table[:minimum].between([1,6])
and as mentioned is available to Arel::Nodes::Node and instances of this class provides a convenience method (create_and) for creating an And so we could do the following:
Arel::Nodes::Node.new.create_and([
MyModel.arel_table[:minimum],
MyModel.arel_table[:maximum]])
There are a number of other ways to hack this functionality together by using other Arel classes but this should get you headed in the right direction.

Rails query the last of each type

I am using STI and have a table Widget that a bunch of other subclasses inherit from using STI. I want a query that gets the last created of each object with a uniq type.
I have a predefined array of types I want so lets say:
types = ["type1", "type2", "type3"]
So my query would be something like: (this doesnt work)
Widget.where(type: types).uniq.reverse
My goal is to get the last of each object that matches 1 of those types..
Not 100% sure, but something like this might work (untested):
ids = Thing.where(type: types).group(:type).maximum(:id).values
last_per_type = Thing.find(ids)
Thing.select("distinct type")
By the way, type is a special variable in rails and can't be used as a column name.

.Currentmember in a named set

I believe that due to the processing order of an analysis services script using context driven functions such as currentmember within a custom set is pointless i.e. the set is evaluated before the processor knows what the currentmember actually is.
Are there any exceptions to the above rule? i.e. what is an example of using the currentmember function within a custom set?
Depending on what you mean by "within a custom set", Currentmember may have its uses. I assume here you meant the usage in the definition expression of the set.
Query level sets take into account the WHERE condition, which may set one or more CurrentMembers.
Cube level named sets may be defined as dynamic since version 2008, hence the same behavior is true.
While you can use CurrentMember in the iteration over a set that Filter and Generate do, you can also use a set alias and the Current property, which I find more clear:
Generate([Customer].[Country].[Country].Members as c,
c.Current.Name,
', '
)
or
Filter([Customer].[Country].[Country].Members as c,
InStr(c.Current.Name, 'a') > 0
)
which could have been written
Generate([Customer].[Country].[Country].Members,
[Customer].[Country].CurrentMember.Name,
', '
)
and
Filter([Customer].[Country].[Country].Members,
InStr([Customer].[Country].CurrentMember.Name, 'a') > 0
)
as well.
Please note that the second case does not deal with the usage of CurrentMember in the definiton of the set that you iterate over, but in the definition of the String or set that results from the Generate or Filter expression.

How should I write an MDX Filter statement with multiple OR conditions efficiently?

In SQL you can compare a field against a set in the form
[Foo] In {"Bar1", "Bar2", ... , "BarN"}
However I'm having trouble working out how to move a filter expression into something like this. That is, for now, I end up with:
Filter(
[MyHierarchy].[Foo].Members,
[MyHierarchy].CurentMember.Name = "1"
OR [MyHierarchy].CurentMember.Name = "2"
...
OR [MyHierarchy].CurentMember.Name = "N"
)
Since I have 20-30 comparisons, and a moderate chance of the heirarchy name changing, I'd much rather maintain a set and a hierarchy name than a long expression. Is there any way to accomplish this?
Worth bearing in mind that the context is an Excel CubeSet function, so I'm a little limited in terms of defining my own members in the WITH clause.
Assuming you have a set named SelectedMembers, you could use
Intersect([MyHierarchy].[Foo].Members, [SelectedMembers])
You could of course also code this directly, i. e.
Intersect([MyHierarchy].[Foo].Members,
{
[MyHierarchy].[Foo].[1],
[MyHierarchy].[Foo].[2],
...
[MyHierarchy].[Foo].[N]
}
)
But it might be more convenient to have the set already defined in the cube calculation script - if that is possible.

How to exclude a certain member from a MDX call that gets all descendants of a member at a higher level

In an OLAP database I work with there is a 'Location' hierarchy consisting of the levels Company -> Region -> Area -> Site -> Room. I am using the following MDX to get all the descendants of a particular member at company level.
DESCENDANTS([Location].[Test Company],[Location].[Site], SELF_AND_BEFORE)
I now have a requirement to exclude a particular Region, named "Redundant", from the report. How can I change the above MDX to exclude this particular Region (and all its descendants)? I know this Region will be called "Redundant" but I do not want to hard-code any of the other Region names, as these may change.
The EXCEPT function will take a set, and remove the members you dont want. In your case you need to say:
EXCEPT(
{DESCENDANTS([Location].[Test Company],[Location].[Site], SELF_AND_BEFORE)},
{DESCENDANTS([Location].[Whatever].[Redundant],[Location].[Site], SELF_AND_BEFORE)}
)
This gives you everything in the first set except what you've mentioned in the second. It's easier to understand like this:
EXCEPT({the set i want}, {a set of members i dont want})
You shouldnt need to worry about the third (optional) argument: http://msdn.microsoft.com/en-us/library/ms144900.aspx
When returning members for your hierarchy simply use "-" to exclude a member you don't want.
This is how I exclude unknown members:
select
{[Module].[Hierarchy].[Module].Members - [Module].[Hierarchy].[Module].[Unknown]} on rows,
{[Date].[Month-day].[Day Of Month].Members - [Date].[Month-day].[Day Of Month].[Unknown]} on columns
from [StatsView]
where {[Measures].[Maintainability Index]}