MDX query on a single dimension - ssas

Can someone please remind me how I do this?
I want an MDX query (MS SSAS) which will query a dimension. Not interested in cubes or measures.
So far as I remember the syntax involves a $ sign, something like [$MyDimension].
I know I can do the below, but I want to query the dimension without touching a cube.
select [DimensionName].Children on 0 from [CubeName]

I guess they're called "dimension cube":
select [dim].members on 0 from [$dim]
or
select [Measures].defaultMember on 0, [dim].members on 1 from [$dim]

Related

SQL - HAVING (execution vs structure)

I'm a beginner, studying on my own... please help me to clarify something about a query: I am working with a soccer database and trying to answer this question: list all seasons with an avg goal per Match rate of over 1, in Matchs that didn’t end with a draw;
The right query for it is:
select season,round((sum(home_team_goal+away_team_goal) *1.0) /count(id),3) as ratio
from match
where home_team_goal != away_team_goal
group by season
having ratio > 1
I don't understand 2 things about this query:
Why do I *1.0? why is it necessary?
I know that the execution in SQL is by this order:
from
where
group
having
select
So how does this query include: having ratio>1 if the "ratio" is only defined in the "select" which is executed AFTER the HAVING?
Am I confused?
Thanks in advance for the help!
The multiplication is added as a typecast to convert INT to FLOAT because by default sum of ints is int and the division looses decimal places after dividing 2 ints.
HAVING. You can consider HAVING as WHERE but applied to the query results. Imagine the query is executed first without HAVING and then the HAVING condition is applied to result rows leaving only suitable ones.
In you case you first select grouped data and calculate aggregated results and then skip unnecessary results of aggregation.
the *1.0 is used for its ".0" part so that it tells the system to treat the expression as a decimal, and thus not make an integer division which would cut-off the decimal part (eg 1 instead of 1.33).
About the second part: select being at the end just means that the last thing
to be done is showing the data. Hoewever, assigning an alias to a calculated field is being done, you could say, at first priority. Still, I am a bit doubtful; I am almost certain field aliases cannot be used in the where/group by/having in, say, sql server.
There is no order of execution of a SQL query. SQL is a descriptive language not a procedural language. A SQL query describes the result set that the query is producing. The SQL engine can execute it however it likes. In fact, most SQL engines compile the query into a directed acyclic graph, which looks nothing like the original query.
What you are referring to might be better phrased as the "order of interpretation". This is more simply described by simple rules. Column aliases can be used in the ORDER BY clause in any database. They cannot be used in the FROM, WHERE, or GROUP BY clauses. Some databases -- such as SQLite -- allow them to be referenced in the HAVING clause.
As for the * 1.0, it is because some databases -- such as SQLite -- do integer arithmetic. However, the logic that you want is probably more simply expressed as:
round((avg(home_team_goal + away_team_goal * 1.0), 3)

How to write an expression for two different attributes in the same field in qlikview

Please help me write the script for the following statement in qlikview which I have it in SQL.
SELECT CASE
WHEN Total_A=0 THEN 0
ELSE cast(((Total_B+Total_C)/Total_A) AS decimal (5,2))
END AS ratio
I have Total_A , Total_B and Total_C in the same field called Total_val
The SQL CASE is usually replaceable by the QlikView if().
Try this
if(Total_A=0,0,(Total_B+Total_C)/Total_A) as Ratio
if the A,B,C switch is inside the Val column then it will get a lot more tricky as you will have to aggregate and use nested ifs. But I believe the statement I wrote is equivalent to the SQL you gave us. If my answer doesn't work please give us a few rows of data to look at

MDX - Why Cross join between measures do not work?

In MDX, we can CROSS JOIN two members, a measure and a member but not two measures. Why is this so? What does it imply?
SELECT
[Measures].[xyz] * [DimTable1].[SomeHierarchy].[Level] on 0,
[DimTable2].[SomeOtherHierarchy].&[Value] on 1
FROM [MyCube]
// WORKS
SELECT
[Measures].[xyz] on 0,
[DimTable2].[SomeOtherHierarchy].&[Value] * [DimTable1].[SomeHierarchy].[Level] on 1
FROM [MyCube]
// OF COURSE IT WORKS
SELECT
[Measures].[xyz] * [Measures].[ABC] on 0,
[DimTable1].[SomeHierarchy].&[Value] on 1
FROM [MyCube]
// DOES NOT WORK!!
I believe you forgot:
SELECT
[dd].[hh].[mm1] * [dd].[hh].[mm2] on 0,
[DimTable1].[SomeHierarchy].&[Value] on 1 FROM [MyCube]
did not work neither. [Measures] is not different than [dd] in my example. In MDX you cannot define a tuple with _ several members _ of the _ same hierarchy _. Have a look to this gentle introduction explaining the main concepts.
EDIT
Your third query, that does not work, looks like this:
The yellow area is empty so it is understandable that it is not happy.
EDIT
Following is an analogy using Excel pivot tables which use OLAP technology
If you put a crossjoin of measures A and B on rows you get something like this:
Then if we add a very small level (with 4 members) onto columns we get the following:
So what will go into the main body of this table?
A count is possible and probably is, in MDX, if you create a custom measure (don't have a server to test this statement on). Excel will default to a count but the result is pretty pointless?

MDX Query SUM PROD to do Weighted Average

I'm building a cube in MS BIDS. I need to create a calculated measure that returns the weighted-average of the rank value weighted by the number of searches. I want this value to be calculated at any level, no matter what dimensions have been applied to break-down the data.
I am trying to do something like the following:
I have one measure called [Rank Search Product] which I want to apply at the lowest level possible and then sum all values of it
IIf([Measures].[Searches] IS NOT NULL, [Measures].[Rank] * [Measures].[Searches], NULL)
And then my weighted average measure uses this:
IIf([Measures].[Rank Search Product] IS NOT NULL AND SUM([Measures].[Searches]) <> 0,
SUM([Measures].[Rank Search Product]) / SUM([Measures].[Searches]),
NULL)
I'm totally new to writing MDX queries and so this is all very confusing to me. The calculation should be
([Rank][0]*[Searches][0] + [Rank][1]*[Searches][1] + [Rank][2]*[Searches][2] ...)
/ SUM([searches])
I've also tried to follow what is explained in this link http://sqlblog.com/blogs/mosha/archive/2005/02/13/performance-of-aggregating-data-from-lower-levels-in-mdx.aspx
Currently loading my data into a pivot table in Excel is return #VALUE! for all calculations of my custom measures.
Please halp!
First of all, you would need an intermediate measure, lets say Rank times Searches, in the cube. The most efficient way to implement this would be to calculate it when processing the measure group. You would extend your fact table by a column e. g. in a view or add a named calculation in the data source view. The SQL expression for this column would be something like Searches * Rank. In the cube definition, you would set the aggregation function of this measure to Sum and make it invisible. Then just define your weighted average as
[Measures].[Rank times Searches] / [Measures].[Searches]
or, to avoid irritating results for zero/null values of searches:
IIf([Measures].[Searches] <> 0, [Measures].[Rank times Searches] / [Measures].[Searches], NULL)
Since Analysis Services 2012 SP1, you can abbreviate the latter to
Divide([Measures].[Rank times Searches], [Measures].[Searches], NULL)
Then the MDX engine will apply everything automatically across all dimensions for you.
In the second expression, the <> 0 test includes a <> null test, as in numerical contexts, NULL is evaluated as zero by MDX - in contrast to SQL.
Finally, as I interpret the link you have in your question, you could leave your measure Rank times Searches on SQL/Data Source View level to be anything, maybe just 0 or null, and would then add the following to your calculation script:
({[Measures].[Rank times Searches]}, Leaves()) = [Measures].[Rank] * [Measures].[Searches];
From my point of view, this solution is not as clear as to directly calculate the value as described above. I would also think it could be slower, at least if you use aggregations for some partitions in your cube.

MDX query: how to select between two cubes?

is it possible to use conditional select ? i want to implement something like that:
if (some_condition)
with ....
select ....
from **cube1**
else
with ...
select ...
from **cube2**
the number of columns may vary depending on cube we are using.
is it possible to make this piece of code work? if yes, how to do this with less blood (i mean with minimal cube amendments)?