VISUALTOTALS and UNION in MDX inconsistent - mdx

I have a problem with a MDX request:
The following query gives me the good partial results
WITH
SET [Paiments Encaisse] AS { [Type Paiement].[Type Paiement Id].&[13]
,[Type Paiement].[Type Paiement Id].&[20]
,[Type Paiement].[Type Paiement Id].&[31]
,[Type Paiement].[Type Paiement Id].&[62]}
MEMBER [Measures].[CA Encaissé]
AS
SUM(
[Paiments Encaisse],[Measures].[Montant HT Partage Encaisse]
)
MEMBER Measures.[CA Encaissé-E] AS [Measures].[CA Encaissé]
MEMBER MEASURES.[CA Encaissé-H] AS
([Measures].[CA Encaissé],[Hors En CDP].[Hors ou En CDP].&[False] )
SELECT
{Measures.[CA Encaissé-E],MEASURES.[CA Encaissé-H]} ON 0,
NON EMPTY{
{[Hors En CDP].[Hors ou En CDP].&[True]} * VISUALTOTALS([Employes].[Hie Societe].MEMBERS)*
[CDP Propriétaire].[Centre de Profits].[All]
} ON 1
FROM NON VISUAL
( SELECT {[Employes].[Societe].&[1234]} ON 0,{[CDP Propriétaire].[Societe].&[1234]} ON 1 FROM [Prévisions] )
WHERE (
[Type Fantome].[Val].&[False],
[Date Facturation du Paiement].[Year].&[2011-01-01T00:00:00],
[Date Paiement].[Year].&[2011-01-01T00:00:00],
[Date Facturation Opération].[Year].&[2011-01-01T00:00:00])
However, the follwoing query, that aims at giving me the whole results, returns me less rows on the first part of the UNION than the first query, which baffles me
WITH
SET [Paiments Encaisse] AS { [Type Paiement].[Type Paiement Id].&[13]
,[Type Paiement].[Type Paiement Id].&[20]
,[Type Paiement].[Type Paiement Id].&[31]
,[Type Paiement].[Type Paiement Id].&[62]}
MEMBER [Measures].[CA Encaissé]
AS
SUM(
[Paiments Encaisse],[Measures].[Montant HT Partage Encaisse]
)
MEMBER Measures.[CA Encaissé-E] AS [Measures].[CA Encaissé]
MEMBER MEASURES.[CA Encaissé-H] AS
([Measures].[CA Encaissé],[Hors En CDP].[Hors ou En CDP].&[False] )
SELECT
{Measures.[CA Encaissé-E],MEASURES.[CA Encaissé-H]} ON 0,
NON EMPTY{ UNION
({[Hors En CDP].[Hors ou En CDP].&[True]} * VISUALTOTALS([Employes].[Hie Societe].MEMBERS)*
[CDP Propriétaire].[Centre de Profits].[All]
, {[Hors en CDP].[Hors ou En CDP].&[False],[Hors en CDP].[Hors ou En CDP].[All]}
* {[Employes].[Hie Societe].[All]} *
VISUALTOTALS ([CDP Propriétaire].[Centre de Profits].ALLMEMBERS
),ALL
)} ON 1
FROM NON VISUAL
( SELECT {[Employes].[Societe].&[1234]} ON 0,{[CDP Propriétaire].[Societe].&[1234]} ON 1 FROM [Prévisions] )
WHERE (
[Type Fantome].[Val].&[False],
[Date Facturation du Paiement].[Year].&[2011-01-01T00:00:00],
[Date Paiement].[Year].&[2011-01-01T00:00:00],
[Date Facturation Opération].[Year].&[2011-01-01T00:00:00])
What's more, the column Measures.[CA Encaissé-H] is always NULL in the second query, even on lines where there should be a value.
What I do not understand is why the results in the first part of the union are influenced by what happens in the second part. Could someone please explain it to me ?

I'm not a specialist of SSAS; but I can share my experience with icCube; VisualTotal() is changing the way a hierarchy is actually aggregated and if you've several calls of this function into the same request this become quite weird as possibly non deterministic (depending on order of evaluation) and difficult to understand.

META : I attached a big bounty to this question, so far, the only answer is a description of the effects, not the inner working of VISUALTOTALS.

Related

How to convert SQL to DAX

I have the following DAX statement but i have no idea how to convert it into a DAX query.
Si([Ticket State]="12. Cerrado / Closed";
NingúnFiltro(Máx([Fecha de Ajuste Final]
En ([Ticket Id];[Create Time Note])) En ([Ticket Id]);Todos);"")
I know that is in spanish, so, if = si and en = in .
Thank you in advance

How to remove multiple possible prefixes from a Name string in SQL Server

I need to correct Names of users by removing prefixes before I can process the names.
For example, my list of prefixes is:
am, auf, auf dem, aus der, d, da, de, de l’, del, de la, de le, di, do, dos, du,
im, la, le, mac, mc, mhac, mhíc, mhic giolla, mic, ni, ní, níc, o, ó,
ua, ui, uí, van, van de, van den, van der, vom, von, von dem, von den, von der
I want to remove any of these prefixes from the First Name if they are present.
For example - inputs:
Outputs:
I know I can take a brute force approach and do a replace 40 odd times, but was wondering if there is a better/smarter way to do this, given the list of names that need to be processed can be in the tens of thousands, daily.
Thank you
You could use apply:
select t.*, v.prefix_free_first_name
from t outer apply
(select top (1) left(t.first_name, len(t.first_name) - len(v.prefix) - 1) as prefix_free_first_name
from (values ('am'), ('auf'), . . .
) v(prefix)
where t.first_name like '% ' + v.prefix
order by len(v.prefix) desc
) v;
Note: This handles the situation where multiple prefixes match a name, such as "de le" and "le".

MDX, Remove Zero-Rows On ROWS

My MDX-Query looks like this:
WITH
MEMBER [YEAR].[A2014_1-12] AS
([YEAR].[2014], [TYPE].[ACTUAL]),
MEMBER [YEAR].[P2014_1-12] AS
([YEAR].[2014], [TYPE].[PLAN]),
MEMBER [YEAR].[P2015_1-12] AS
([YEAR].[2015], [TYPE].[PLAN]),
MEMBER [YEAR].[A2015_YTD] AS
SUM(
{[YEARPERIOD].[201501]:[YEARPERIOD].[201509]}
,(
[Measures].currentmember
,[TYPE].[ACTUAL]
)
)
SELECT
{
[YEAR].[A2014_1-12],
[YEAR].[P2014_1-12],
[YEAR].[P2015_1-12],
[YEAR].[A2015_YTD]
}
ON COLUMNS,
NON EMPTY
[COST_CENTER]
*[COST_ELEMENT] ON ROWS
FROM [CUBE]
WHERE ([Measures].[COSTS]);
The Query itself is working. However it is also returning a lot of zero-rows and I would like to get rid of these zero-rows. The strange thing is - If I put only one MEMBER (e.g. [YEAR].[A2014_1-12]) on the COLUMNS-axis it is not returning any zero-rows. But as soon as I start to add another MEMBER to the COLUMN-axis it is also many returning zero-rows (It seems like it is ignoring the NON EMPTY in my CROSSJOIN). How can I remove the zero-rows in the above MDX-Query?
Try this as a start
WITH
MEMBER [YEAR].[A2014_1-12] AS
iif(
([YEAR].[2014], [TYPE].[ACTUAL]) = 0
,null
,([YEAR].[2014], [TYPE].[ACTUAL])
)
MEMBER [YEAR].[P2014_1-12] AS
iif(
([YEAR].[2014], [TYPE].[PLAN]) = 0
,null
,([YEAR].[2014], [TYPE].[PLAN])
)
SELECT
NON EMPTY
{
[YEAR].[A2014_1-12],
[YEAR].[P2014_1-12]
}
ON COLUMNS,
NON EMPTY
[COST_CENTER]
*[COST_ELEMENT] ON ROWS
FROM [CUBE]
WHERE ([Measures].[COSTS]);
As an aside you do not need to define the current member of the measures hierarchy in this definition:
MEMBER [YEAR].[A2015_YTD] AS
SUM(
{[YEARPERIOD].[201501]:[YEARPERIOD].[201509]}
,(
[Measures].currentmember
,[TYPE].[ACTUAL]
)
)
This is enough:
MEMBER [YEAR].[A2015_YTD] AS
SUM(
{[YEARPERIOD].[201501]:[YEARPERIOD].[201509]}
,([TYPE].[ACTUAL])
)
Try this instead:
WITH
MEMBER [YEAR].[A2014_1-12] AS
iif(
([YEAR].[2014], [TYPE].[ACTUAL]) = 0
,null
,([YEAR].[2014], [TYPE].[ACTUAL])
)
MEMBER [YEAR].[P2014_1-12] AS
iif(
([YEAR].[2014], [TYPE].[PLAN]) = 0
,null
,([YEAR].[2014], [TYPE].[PLAN])
)
SET [X] AS
NonEmtpy(
[COST_CENTER]*[COST_ELEMENT],
{[YEAR].[A2014_1-12],[YEAR].[P2014_1-12]}
)
SELECT
NON EMPTY
{
[YEAR].[A2014_1-12],
[YEAR].[P2014_1-12]
}
ON 0,
//NON EMPTY
[X] ON 1
FROM [CUBE]
WHERE ([Measures].[COSTS]);

The Axis0 function expects a tuple set expression for the argument

I just want to get the invoices distinct count of sales on March. I got this MDX query.
My MDX Query:
select
distinctcount([Measures].[Sales #]) on columns,
--[Measures].[Sales #] on columns,
non empty ([Customer].[Store Group].[Store Group]) on rows
from
(
select
{
[Calendar].[Month].[March 2015]
}
ON columns
from [F1_SalesBI])
But I got the following error, whenever I tried executing this.
Executing the query ...
The Axis0 function expects a tuple set expression for the argument. A string or numeric expression was used.
Execution complete
Here is the definition from msdn:
https://msdn.microsoft.com/en-us/library/ms145519.aspx
Syntax:
DistinctCount(Set_Expression)
You're doing this when you use Measures as the argument:
DistinctCount(Numeric_Expression)
Something like the following should hopefully run ok:
WITH
SET [mySet] AS
[Customer].[Store Group].[Store Group] * {[Measures].[Sales #]}
MEMBER [Measures].[setDistCount] AS
DistinctCount([mySet])
SELECT
{
[Measures].[setDistCount]
,[Measures].[Sales #]
} ON 0
,NON EMPTY
[Customer].[Store Group].[Store Group] ON 1
FROM
(
SELECT
{[Calendar].[Month].[March 2015]} ON 0
FROM [F1_SalesBI]
);
To return the number of invoices for the month try the following:
WITH
SET [mySet] AS
{[Calendar].[Month].[March 2015]} * {[Measures].[Sales #]}
MEMBER [Measures].[setDistCount] AS
DistinctCount([mySet])
SELECT
{
[Measures].[setDistCount]
} ON 0
FROM [F1_SalesBI];
If the above returns 1 then try inspecting the set via this script:
SELECT
{} on 0,
{[Calendar].[Month].[March 2015]} * {[Measures].[Sales #]} ON 0
FROM [F1_SalesBI];
Does this just return 1 member?
How about this (without the set braces around the measure)?:
SELECT
{} on 0,
{[Calendar].[Month].[March 2015]} * [Measures].[Sales #] ON 0
FROM [F1_SalesBI];

MDX results to Excel in Power Pivot

I don't know ABCDs of MDX. I have this query that was handed over to me by my predecessor and that it is needed only once in a year! That time of the year happens to be now! The query runs and returns the results. However, I am unable to copy the result along with the rows and column names from the SSAS result window.
Googling I found the options of Linked servers, setting query options to save the result as csv etc, using SSIS packages and PowerPivot.
The first two are not possible because of restrictions on the DB. I need to go over a bunch of corporate hurdles to get the necessary permissions.
SSIS packages and Power Pivot - have the same issue. 'BUD' is a named set and it is referenced in the filter below in select statement. Both SSIS (when typed in OLEDB Source) throws error - The dimension [BUD] was not found.
Working with PowerPivot, I executed set create statement separately and then pasted only the code after 'WITH'. The Error was -The dimension [BUD] was not found.
Any help of how to reference the BUD in the select statement for Power Pivot or SSIS? I am using sqlsever2008r2.
This the procedure -
create set [DB1].BUD AS
nonemptycrossjoin(
{[Market].[Markets].&[Europe].children,[Market].[Markets].[Part of World].&[Africa].children},
[Product].[PL].&[CD] : [Product].[PL].&[KZ],
[Plant].[Plant].children
) go
with
member measures.callsCY1 as
/* Lot of measure calutaions here */
select
non empty
{
[Measures].[Qty Sold],
callsCY1,costCY1,MTRLcostCY1,LabourCostCY1,
SCR_C,callsRY1,costRY1,MTRLcostRY1,LabourCostRY1,
callsCY2,costCY2,MTRLcostCY2,LabourCostCY2,
callsRY2,costRY2,MTRLcostRY2,LabourCostRY2,
callsCY3,costCY3,MTRLcostCY3,LabourCostCY3,
callsRY3,costRY3,MTRLcostRY3,LabourCostRY3
}
*
{[Report Period].[Report Periods].[Quarter].&[2013-01-01T00:00:00] : [Report Period].[Report Periods].[Quarter].&[2014-06-01T00:00:00]}
on 0,
non empty
filter(
bud, [Measures].[Qty Sold] <> 0 OR [Measures].[QTY Service Calls] <> 0)
on 1
from [db1]
Does bud need to be seperate? Can't you just use this?
with
set [BUD] AS
nonemptycrossjoin(
{[Market].[Markets].&[Europe].children,[Market].[Markets].[Part of World].&[Africa].children},
[Product].[PL].&[CD] : [Product].[PL].&[KZ],
[Plant].[Plant].children
)
member measures.callsCY1 as
/* Lot of measure calutaions here */
select
non empty
{
[Measures].[Qty Sold],
callsCY1,costCY1,MTRLcostCY1,LabourCostCY1,
SCR_C,callsRY1,costRY1,MTRLcostRY1,LabourCostRY1,
callsCY2,costCY2,MTRLcostCY2,LabourCostCY2,
callsRY2,costRY2,MTRLcostRY2,LabourCostRY2,
callsCY3,costCY3,MTRLcostCY3,LabourCostCY3,
callsRY3,costRY3,MTRLcostRY3,LabourCostRY3
}
*
{[Report Period].[Report Periods].[Quarter].&[2013-01-01T00:00:00] : [Report Period].[Report Periods].[Quarter].&[2014-06-01T00:00:00]}
on 0,
non empty
filter(
bud, [Measures].[Qty Sold] <> 0 OR [Measures].[QTY Service Calls] <> 0)
on 1
from [db1]