I need to replace nulls with 0 in a crossjoin result of a mdx query.
This is my query:
WITH
MEMBER [Measures].[X] AS
([Indicador].[Indicador Descrição].&[X],[Measures].[MONTANTE])
MEMBER [Measures].[Y] AS
([Indicador].[Indicador Descrição].&[Y],[Measures].[MONTANTE])
SELECT
NON EMPTY {[Measures].[X],[Measures].[Y]} ON COLUMNS,
NON EMPTY{[Classificador Orgânico].[A].children*
[Programas e Medidas].[A].children*
[Classificador Económico Despesa].[A].children*
[Classificador Económico Despesa].[B].children*
[Classificador Económico Despesa].[C].children*
[Classificador Económico Despesa Rubricas].[A].children*
[Classificador Económico Despesa Rubricas].[B].children*
[Fonte de Financiamento].[A].children} ON ROWS
FROM [Cube]
WHERE ([Calendar].[Year].&[2018],[Calendar].[Month].&[04])
I already try to use coalesceempty in the calculated members but replaces all the nulls before the NonEmptyCrossjoin (the query doesn't even answer).
The ideal solution is to replace nulls only after the NonEmptyCrossjoin .What is the proper way to achieve that?
Thanks!
Regards, Cristiana Dias
Can you try with:
WITH
MEMBER [Measures].[X] AS
([Indicador].[Indicador Descrição].&[X],[Measures].[MONTANTE]), FORMAT_STRING = '#,##0.00;-#,##0.00;;0'
MEMBER [Measures].[Y] AS
([Indicador].[Indicador Descrição].&[Y],[Measures].[MONTANTE]), FORMAT_STRING = '#,##0.00;-#,##0.00;;0'
SELECT
NON EMPTY {[Measures].[X],[Measures].[Y]} ON COLUMNS,
NON EMPTY{[Classificador Orgânico].[A].children*
[Programas e Medidas].[A].children*
[Classificador Económico Despesa].[A].children*
[Classificador Económico Despesa].[B].children*
[Classificador Económico Despesa].[C].children*
[Classificador Económico Despesa Rubricas].[A].children*
[Classificador Económico Despesa Rubricas].[B].children*
[Fonte de Financiamento].[A].children} ON ROWS
FROM [Cube]
WHERE ([Calendar].[Year].&[2018],[Calendar].[Month].&[04])
I have just added FORMAT_STRING. The first argument is how positive values should be formatted, the second is how negative values should be formatted, the third argument is how 0 values should be formatted, and the fourth argument is how NULL should be formatted - display a 0 instead.
The problem with using CoalesceEmpty or isEmpty like this
IIF(ISEMPTY(([Indicador].[Indicador Descrição].&[X],[Measures].[MONTANTE])) , 0 , ([Indicador].[Indicador Descrição].&[X],[Measures].[MONTANTE]))
is that you are filling empty cells in the cube with zeros, so result set of cross join will be huge, and query probably won't finish at all.
Related
In the following MDX query, I want to set the value of [Measures].[Label] as the string literal "Net Value" instead of NULL (i.e. using a string literal to populate the values in the label column). I'm scratching my head about how to do this in MDX. Tons of background with SQL, but a relative newbie with SSAS.
`WITH
Member [Measures].[Label] AS NULL
Member [Measures].[Value] AS [Measures].[Net Amt]
SELECT NON EMPTY
(
{[Time].[Quarter].[Quarter]},
{[Time].[Month].[Month]},
{[Time].[Work Week].[Work Week]},
{[Customer].[Region Cd].[Region Cd]},
{[Product].[Cd Nm].[Cd Nm]}
) ON Rows,
NON EMPTY
(
{
[Measures].[Value],
[Measures].[Label]
}
) ON Columns
FROM [Reporting]
WHERE
(
{
[Time].[Year].[Year].&[2022]:[Time].[Year].[Year].&[2023]
},
{[Segment].[Segment Nm].[Segment Nm].&[SEG VALUE]}
)`
If I try a value in double quotes, the query just times out without finishing. Just using a null like this only takes 2 seconds to return.
Member [Measures].[Label] AS "Net Amt"
The problem with putting a constant is that the NON EMPTY now returns every combination of Time, Customer and Product.
Instead you want to return a constant but only on rows where the Net Amt measure is not empty.
Member [Measures].[Label] AS IIF(Not(IsEmpty([Measures].[Net Amt])),"Net Amt",Null)
Alternately you could use a constant but use the NonEmpty function instead against the Net Amt measure only:
Member [Measures].[Label] AS "Net Amt"
Member [Measures].[Value] AS [Measures].[Net Amt]
SELECT NonEmpty(
{
{[Time].[Quarter].[Quarter]}*
{[Time].[Month].[Month]}*
{[Time].[Work Week].[Work Week]}*
{[Customer].[Region Cd].[Region Cd]}*
{[Product].[Cd Nm].[Cd Nm]}
},
[Measures].[Net Amt]
) ON Rows,
{
[Measures].[Value],
[Measures].[Label]
}
ON Columns
I have a query that looks at one tables field and matches the second table's field. It looks to see if the fields don't match each other. If there's no match the second table's field must replace the first tables field. I have this working EXCEPT when there's a null value in either of the two tables field. I tried using isNull() on the first table and it does select values that aren't null but if I apply the same function to the second table I get nothing in return.
UPDATE [NAVAIR Deficiencies] INNER JOIN NAVAIR_Deficiencies_Temp ON [NAVAIR Deficiencies].[Unique Deficiency Code] = NAVAIR_Deficiencies_Temp.[Unique Deficiency Code] SET [NAVAIR Deficiencies].[Hull Q] = [NAVAIR_Deficiencies_Temp]![Hull Q], NAVAIR_Deficiencies_Temp.Changed = True
WHERE ((IsNull([NAVAIR Deficiencies]![Hull Q])<>[NAVAIR_Deficiencies_Temp]![Hull Q]));
You are experiencing the fact that null <> null.
You can work around this with IsNull(), if you are able to define a string value that never appears in both columns:
IsNull([NAVAIR Deficiencies]![Hull Q], '§§§§')
<> IsNull([NAVAIR_Deficiencies_Temp]![Hull Q], '§§§§')
This treats two null value as equals, and considers that a null value is not equal to any non-null value.
Or, you can enumerate all possible situations, using boolean logic
[NAVAIR Deficiencies]![Hull Q]) <> [NAVAIR_Deficiencies_Temp]![Hull Q]
or ([NAVAIR Deficiencies]![Hull Q] is null and [NAVAIR_Deficiencies_Temp]![Hull Q] is not null)
or ([NAVAIR Deficiencies]![Hull Q] is not null and [NAVAIR_Deficiencies_Temp]![Hull Q] is null)
It might be simpler expressed with a negation:
not (
[NAVAIR Deficiencies]![Hull Q]) = [NAVAIR_Deficiencies_Temp]![Hull Q]
or ([NAVAIR Deficiencies]![Hull Q] is null and [NAVAIR_Deficiencies_Temp]![Hull Q] is null)
)
I want to search date between two columns of same dimension. Columns name is start date and end date. I tried every thing, following query give me this error : Mondrian Error:Internal error: Cannot deduce type of call to function ':'
MDX query :
WITH
SET [~ROWS] AS
Hierarchize
(
{
{[Location_Cluster.default].[All Location_Cluster.defaults]}
,{[Location_Cluster.default].[Location_Cluster].MEMBERS}
}
)
MEMBER [Measures].[QTY Percent] AS
[Measures].[Total_Quantity]
/
(
[Measures].[Total_Quantity]
,[Location_Cluster.default].[All Location_Cluster.defaults]
)
,format_string = '0.00%'
MEMBER [Measures].[Revenue Percent] AS
[Measures].[Total_Revenue]
/
(
[Measures].[Total_Revenue]
,[Location_Cluster.default].[All Location_Cluster.defaults]
)
,format_string = '0.00%'
MEMBER [Measures].[Margin Percent] AS
[Measures].[Total_Margin]
/
(
[Measures].[Total_Margin]
,[Location_Cluster.default].[All Location_Cluster.defaults]
)
,format_string = '0.00%'
SELECT
NON EMPTY
{
[Measures].[Sku_Count]
,[Measures].[Total_Quantity]
,[Measures].[QTY Percent]
,[Measures].[Total_Revenue]
,[Measures].[Revenue Percent]
,[Measures].[Total_Margin]
,[Measures].[Margin Percent]
} ON COLUMNS
,NON EMPTY
[~ROWS] ON ROWS
FROM [APCS_SALES_CUBE]
WHERE
(
{[Date].[Start_Date].&[2017-01-01] : NULL}
,{NULL : [Date].[End_Date].&[2017-03-01]}
,[Cluster.Cluster_Id].[2]
,[Taxonomy.default].[Taxonomy_ID].[3]
,[Company.Company_Name].[Compnay_Name].[1]
);
I followed following links to resolve this issue. But don't know how to apply specify function in Mondrian MDX
https://ask.sqlservercentral.com/questions/95478/mdx-for-records-between-date-range-where-start-and.html#answer-142811
https://www.purplefrogsystems.com/blog/2013/04/mdx-between-start-date-and-end-date/#comment-1981
Your query is not well formed. You need to make set out of the range you want to slice. Here is an example:
WITH SET [~ROWS] AS
(${dateFromParameter} : ${dateToParameter})
MEMBER Measures.[number] as
FORMAT([date].[godina].CurrentMember.PROPERTIES("datum"), "dd.mm.yyyy")
SET [ROOT] AS
FILTER([ORG].[org_id].Members, [ORG].[org_id].currentmember.parent.parent=[ORG].[org_id].currentmember.parent)
SELECT
NON EMPTY {[Measures].[total], Measures.[number]} ON COLUMNS,
NON EMPTY [ROOT] * [~ROWS] ON ROWS
FROM [svcs]
This MDX function raise error :
with member measures.x as
(
[Date].[Date].[Date].&[20160101] : [Date].[Date].[Date].currentmember.value
,
[Measures].[current balance]
)
select measures.x on columns,
[Branch].[HeadOffice Branch].[Head Office Code] on rows
from MyCube
Error is :
The CURRENTMEMBER function expects a hierarchy expression for the 1 argument. A member expression was used.
But when I use
[Date].[Date].[Date].&[20160101] : [Date].[Date].[Date].&[20160131]
It works good
why?
This is valid mdx:
[Date].[Date].[Date].&[20160101] : [Date].[Date].currentmember
Although this is not:
WITH member measures.x AS
(
[Date].[Date].[Date].&[20160101] : [Date].[Date].currentmember
,
[Measures].[current balance]
)
It is not valid because round braces (...) signify a tuple but a tuple requires exact co-ordinates so the first argument cannot be a set.
You could add an aggregation such as SUM:
WITH member measures.x AS
SUM
(
[Date].[Date].[Date].&[20160101] : [Date].[Date].currentmember
,
[Measures].[current balance]
)
This is valid mdx but if you do not have [Date].[Date] in context i.e. in the WHERE or SELECT clause then all it is returning is the All member.
Why are you using [Date].[Date].currentmember ?
CURRENTMEMBER works on an attribute hierarchy (in your case [Date].[Date]). So [Date].[Date].CURRENTMEMBER will work.
Also you will need to take out the value selector, as your expression returns a set of dates (member : member returns a set of all the members between those two members).
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]);