Multiple Sets in MDX using WITH function - mdx

Starting to learn MDX as one of the databases at work is based around a Cube
I have an SQL background so worked my way round understanding Tuples and Sets.
Where I am getting stuck is if I wanted to define multiple sets how can I do this via the WITH function. Following function works fine when I am defining one set with WITH function but surely there must be a way to define multiple sets.
Apologies if very basic function, I did try the search box but perhaps wasn't phrasing the request correctly.
Thanks in advance for any help
WITH SET
[MARKET] AS {[Location].&[Australia],[Location].[Singapore]},
[CALENDAR] AS {[Calendar].&[April,2018],[Calendar].&[May,2018]}
SELECT
{([Measures].[Money]),([Measures].[Target])} on 0,
{([CALENDAR],[MARKET],[Sales Department])}on 1
FROM AussieDatabase

You need to define each set explicitly, they can then be cross joined on rows
WITH
SET [MARKET] AS
{[Location].&[Australia]
,[Location].[Singapore]},
SET [CALENDAR] AS
{[Calendar].&[April,2018]
,[Calendar].&[May,2018]}
SELECT
{
[Measures].[Money]
,[Measures].[Target]
} on 0,
[CALENDAR] * [MARKET] on 1
FROM AussieDatabase;

Related

Filter in WHERE using Named Set

Is it possible to use an aggregated named set to filter queries in MDX? I don't want the set items in the result set so moved it to the WHERE, however this seems to cause all measures to return (null).
First, I build a set using a couple of members from a staff hierarchy:
WITH
SET [Combined] as {
[Staff].[Group].[Practice Group].&[04],
[Staff].[Group].[Practice Group].&[06]
}
Then I aggregate that set into a new member:
MEMBER [Staff].[Group].[Group Combo] AS Aggregate([Combined])
Usually I would then use this in my query as a reporting area, possibly with hierarchize (depending on the query) and everything is fine. However this time I needed to filter the data based on this combination of members e.g:
WHERE ([Staff].[Group].[Group Combo])
This gave me (null) values and if I used [Combined] I received a cyclical reference error, however using the below worked fine:
WHERE ({[Staff].[Group].[Practice Group].&[04],[Staff].[Group].[Practice Group].&[06]})
Am I overlooking something here? Or using the wrong approach? Maybe it is just a quirk of the cube I am querying?
I would say that the behaviour is related to the order in which the processor is executing the clauses within your query:
Logical order an MDX query is processed
WHERE happens before WITH
You mentioned that the following works fine - specifying explicit members in the where clause it is pretty standard and fast:
WHERE ({[Staff].[Group].[Practice Group].&[04],[Staff].[Group].[Practice Group].&[06]})
You could add it to a sub-select just as it is on the 0 axis:
SELECT
...
...
FROM
(
SELECT
{[Staff].[Group].[Practice Group].&[04],[Staff].[Group].[Practice Group].&[06]} ON 0
FROM [YourCube]
);

SSAS: Two sets specified in the function have different dimensionality

I'm trying to run the following MDX query (I'm newbie in the matter):
WITH MEMBER [Measures].[Not Null SIGNEDDATA] AS IIF( IsEmpty( [Measures].[SIGNEDDATA] ), 0, [Measures].[SIGNEDDATA] )
SELECT
{[Measures].[Not Null SIGNEDDATA]} ON COLUMNS,
{[Cuenta].[818000_001],[Cuenta].[818000_G02]} ON ROWS
FROM [Notas_SIC]
WHERE ([Auditoria].[AUD_NA],[Concepto].[CONCEPTO_NA],[Entidad].[CCB],
[Indicador].[INDICADOR_NA],[Interco].[I_NONE],[Moneda].[COP],
[Tiempo].[2010.01],[Version].[VERSION_NA])
Where 818000_001 is a base member of my 'Cuenta' dimension, and 818000_G02 is a node or aggregation. I receive the following message:
"Two sets specified in the function have different dimensionality"
What am I doing wrong? If I put the query with only base members (many) or only differents aggregations, the result is ok as expected.
Thanks in advance!
By using commas in your WHERE clause, you are trying to create a set out of members from different dimensions. You should use asterisks to make a CROSSJOIN instead.
So replace this:
WHERE ([Auditoria].[AUD_NA],[Concepto].[CONCEPTO_NA],[Entidad].[CCB],
[Indicador].[INDICADOR_NA],[Interco].[I_NONE],[Moneda].[COP],
[Tiempo].[2010.01],[Version].[VERSION_NA])
With this:
WHERE ({[Auditoria].[AUD_NA],[Concepto].[CONCEPTO_NA],[Entidad].[CCB]} *
{[Indicador].[INDICADOR_NA],[Interco].[I_NONE],[Moneda].[COP]} *
{[Tiempo].[2010.01],[Version].[VERSION_NA]})
I added curly braces though I'm not sure if they're absolutely required.
This is maybe your problem:
{[Cuenta].[818000_001],[Cuenta].[818000_G02]} ON ROWS
You have put them as a set but you can only make a set out of members with the same dimensionality. From your description it sounds like [Cuenta].[818000_G02] is being classed as a different hierarchy which is unexpected.
Is [Cuenta].[818000_G02] created using the Aggregate function? Can you swap to using the Sum function? Does the script then work?
(not a great answer - just more questions?)
{[Cuenta].[818000_001],[Cuenta].[818000_G02]}
Your problem probably lies in the above statement. As is clear, they could be from different hierarchies(which is not clear from your example and I come to that below).
Try replacing the above with
{[Cuenta].[Hierarchy1].[818000_001]} * {[Cuenta].[Hierarchy2].[818000_G02]}
where Hierarchy1 and Hierarchy2 are the hierarchies to which these members belong. (If you are not sure, just try {[Cuenta].[818000_001]} * {[Cuenta].[818000_G02]}). I am assuming that the second aggregate members may be built on a different hierarchy and thus the engine is throwing an error.
It is generally a good habit to always use the fully qualified member name because then the SSAS engine has to spend less time in searching for the member.

Avoiding writing of same block of statements at different places in one code in SQL SERVER 2008

There are 3 views and one of them is Time view. All 3 views take the same code used for inserting Time factor( financial period, financial year, quarter) for which I have to write same code in all three views.
Please suggest how to do it without writing the whole code each time.
Create an inline table defined function which accepts a parameter and returns a variety of date functions applied to the parameter. Then use CROSS APPLY to fetch the ones of interest in any given query.
You can use cursor also to achieve the desired result. For example, pass the parameter to the cursor, do the calculation inside of the cursor, then return it.
Cross apply will also work.

Showing unconstant number of columns in Reporting Services

i have a query which returns unconstant number of columns.
How can i use this in reporting services?
SET #aaa = ( 'select '+ #str+ ' from personel.fnt_hede(1,21,0) ')
EXECUTE (#aaa )
somehow i generate #str and use in this way.
I hope , i expressed myself clearly :)
thanks in advance..
One option, is to return a fixed set of columns (assuming there is a definable set) and then show/hide the appropriate columns in the report.
Or, you could use a Matrix in your report. You would have to return data in a different approach though, basically as a list of key/value data values that the Matrix can pivot. Here's a post that came in handy when I was looking into this scenario. This approach turned out to work well in a situation where I too do not know up front how many columns (or what their names are going to be) up front.
You can't - SSRS needs a clearly defined resultset to be able to design reports.
Instead of using a custom query, use a query with all the available fields included, and then pass parameter values to the report to indicate which ones should be displyed.

Is there a way to specify that every cell should be brought back using MDX?

I'm using a query of the form:
Select {
([Measures].[M1], [Time].[2000]),
([Measures].[M2], [Time].[2000]),
([Measures].[M1], [Time].[2001]),
([Measures].[M2], [Time].[2001])
} on 0
From [Cube]
Where
([Some].[OtherStuff])
using Analysis Services 2008. Even though I'm not specifying NON EMPTY or similar, I'm still only getting three of the cells back (one of them is null).
How do I make sure that all the cells are brought back - even null ones?
Additional thoughts:
The query above isn't actually the one I'm running (surprisingly enough:) ). The real one has a couple of hierarchies from the same dimension specified as part of the select, and also as part of the where clause. I'm wondering if it's something to do with that, but I can't think what exactly.
Additional additional thoughts:*
This seems to be an AS2005/8 feature called Auto-Exists. Have a look at the relevant section on this MSDN article.
You're pulling back different dimensions, which doesn't fly too well. Try this instead:
with
member [Time].[Calendar].[CY2000] as
([Time].[Calendar].[2000], [Time].[Fiscal].[All Time])
member [Time].[Calendar].[FY2001] as
([Time].[Calendar].[All Time], [Time].[Fiscal].[2001])
select
{[Time].[Calendar].[CY2000], [Time].[Calendar].[FY2001]}*
{[Measures].[M1], [Measures].[M2]}
on columns
from [Cube]
where
{[Some].[OtherOtherStuff]}
Not an answer but this should help narrow down the problem, a query that replicates the issue in AdventureWorks
SELECT
{ ( [Date].[Calendar].[Date].&[1], [Date].[Fiscal].[Date].&[1129] ) } on 0
FROM [Adventure Works]
I'd expect this to bring back the tuple specified and a Null, but instead no tuples are retrieved.
I think this is because the tuple located on two hierarchies of the same dimension where there is no commonality.