Issues using mdx generated from PivotTable - pivot-table

I recently used excel to connect to analysis services and generate a mdx code that was used to query the cube. The code is shown below. The code was also verified using sql profiler. However when I go to analysis services and browse the cube and put in the cube in management studio, I get errors. Please let me know if the code can be fixed. This code is exactly what i need for my requirements so if there are any modifications please replace it within the cube itself.
Code
SELECT NON EMPTY Hierarchize(DrilldownMember(CrossJoin({
[ColorsDim].[PrimeColor].[All], [ColorsDim].[PrimeColor].[PrimeColor].AllMember},
{([ColorsDim].[SecondColor].[All]) }), [ColorsDim].[PrimeColor].[PrimeColor].AllMember,
[ColorsDim].[SecondColor])) DIMENSION PROPERTIES PARENT_UNIQUE_NAME
,HIERARCHY_UNIQUE_NAME ON COLUMNS
,NON EMPTY Hierarchize({DrilldownMember({
[ColorsDim].[Color_id].[All] },,, INCLUDE_CALC_MEMBERS) }) DIMENSION PROPERTIES
PARENT_UNIQUE_NAME
,HIERARCHY_UNIQUE_NAME ON ROWS FROM [Model]
WHERE ([Measures].[Number of records in ColorDim]) CELL PROPERTIES VALUE
,FORMAT_STRING
,BACK_COLOR
,FORE_COLOR
,FONT_FLAGS
Error
Query Preparation failed.
Additional information
The query cannot be prepared: The query must have at least one axis. The first axis of the query should not have mulitple hierarchies, nor should it reference any dimension other than the measures dimension..
Parameter name: mdx (MDXQueryGenerator)
Desired Output
The following query shows the desired output:
Select non empty
[ColorsDim].[PrimeColor].children *
[ColorsDim].[SecondColor].children
on 0
, non empty
[ColorsDim].[Color_id].children
on 1
from [model]
where [Measures].[Number of records in ColorDim];
The measure in the query is a count of rows for that particular dimension

Well the error message you've provided looks to me like an SSRS error message.
If you open SSMS with a connection to the cube and then open an mdx query the query should run ok.
Reformatting the query so we can see more clearly what is happening gives this:
SELECT
NON EMPTY
Hierarchize(
DrilldownMember(
CrossJoin(
{[ColorsDim].[PrimeColor].[All]
, [ColorsDim].[PrimeColor].[PrimeColor].AllMember}
,{([ColorsDim].[SecondColor].[All]) }
)
, [ColorsDim].[PrimeColor].[PrimeColor].AllMember
, [ColorsDim].[SecondColor]
)
) DIMENSION PROPERTIES PARENT_UNIQUE_NAME
,HIERARCHY_UNIQUE_NAME ON COLUMNS
,NON EMPTY
Hierarchize(
{
DrilldownMember(
{[ColorsDim].[Color_id].[All] }
,,, INCLUDE_CALC_MEMBERS
)
}
)
DIMENSION PROPERTIES PARENT_UNIQUE_NAME
,HIERARCHY_UNIQUE_NAME ON ROWS
FROM [Model]
WHERE ([Measures].[Number of records in ColorDim])
CELL PROPERTIES VALUE
,FORMAT_STRING
,BACK_COLOR
,FORE_COLOR
,FONT_FLAGS
Excel adds a lot of boilerplate code so we can get rid of the cell and dimension properties, I suspect hierarchize is not needed, and the crossjoin can be replaced with the simple * operator, to give this:
SELECT
NON EMPTY
DrilldownMember(
[ColorsDim].[PrimeColor].[All]
* [ColorsDim].[PrimeColor].[PrimeColor].AllMember
,{([ColorsDim].[SecondColor].[All])}
)
, [ColorsDim].[PrimeColor].[PrimeColor].AllMember
, [ColorsDim].[SecondColor]
)
ON 0
,NON EMPTY
DrilldownMember(
{[ColorsDim].[Color_id].[All] }
,,, INCLUDE_CALC_MEMBERS
)
ON 1
FROM [Model]
WHERE [Measures].[Number of records in ColorDim];
If you want to use this in SSRS then you will need to re-write it so that COLUMNS (or 0) only uses the dimension Measures!
To make it so that ssrs is happy enough you could do this:
WITH
MEMBER [Measures].[Green_YellowGreen] AS
(
[ColorsDim].[PrimeColor].[PrimeColor].[Green],
[ColorsDim].[PrimeColor].[SecondColor].[Yellow-Green],
[Measures].[Number of records in ColorDim]
)
MEMBER [Measures].[Green_BlueGreen] AS
(
[ColorsDim].[PrimeColor].[PrimeColor].[Green],
[ColorsDim].[PrimeColor].[SecondColor].[Blue-Green],
[Measures].[Number of records in ColorDim]
)
SELECT
NON EMPTY
{[Measures].[Green_YellowGreen], [Measures].[Green_BlueGreen] }
ON 0
, NON EMPTY
[ColorsDim].[Color_id].children
ON 1
FROM [model];

Related

How to merge multiple records with strings and nulls in a Stream Analytics Group By

I am trying to pull some logged events from Application Insights into our SQL database. I have no control over the format of the inputs which are json files composed of multiple json arrays within the file. In each record, 5 pieces of information are in a json array at [context].[custom].[dimensions] in the file and using an OUTER APPLY flattens these values. The problem is it returns results not as one row per record but as though you had joined one row with 5 (which is indeed what it has done) and the values of the 5 pieces of data are NULL in 4 cases and the actual value in the other. I only need 2 of the 5 values - PageType and UserId - and given this in my GROUP BY it returns 3 records, one with each value and one with both of them null.
In normal SQL you would simply use a MAX expression to get the real values for each but in Stream Analytics you can't use MAX on strings. You also can't use COALESCE and a number of other methods I tried to resolve this with. Any ideas how the results can be changed from:
EventDateTime Event PageType UserId AppVersion CountA
2017-05-24 Nav Show NULL NULL 2.0.1293 1
2017-05-24 Nav Show NULL SIRTSW 2.0.1293 1
2017-05-24 Nav Show Trade NULL 2.0.1293 1
to
2017-05-24 Nav Show Trade SIRTSW 2.0.1293 1 ?
The code that returns three rows for each is as follows (note that e.event is an array of one item so it does not cause the same issue):
SELECT flatEvent.ArrayValue.name as Event,
e.context.data.eventTime as EventDateTime,
e.context.application.version as AppVersion
,flatCustom.ArrayValue.UserId as UserId
,flatCustom.ArrayValue.PageType as PageType,
SUM(flatEvent.ArrayValue.count) as CountA
INTO
[insights]
FROM [ios] e
CROSS APPLY GetArrayElements(e.[event]) as flatEvent
OUTER APPLY GetArrayElements(e.[context].[custom].[dimensions]) as flatCustom
GROUP BY SlidingWindow(minute, 1),
flatEvent.ArrayValue.name,
e.context.data.eventTime,
e.context.application.version,
flatCustom.ArrayValue.UserId,
flatCustom.ArrayValue.PageType
Thanks in advance,
Rob
According to your scenario, I assumed that you could use JavaScript user-defined functions for Azure Stream Analytics to coalesce the multiple dimensions into a single record. Here are my test for this issue, you could refer to them.
JSON file
{
"context":{
"data":{"eventTime":"2017-05-24"},
"application":{"version":"2.0.1293"},
"custom":{
"dimensions":[
{"PageType":null,"UserId":"SIRTSW"},
{"PageType":"Trade","UserId":null},
{"PageType":null,"UserId":null}
]
}
},
"event":[
{"name":"Nav Show","count":1}
]
}
javascript UDF, UDF.coalesce
function main(items) {
var result=[];
var UserIdStr="",PageTypeStr="";
for(var i=0;i<items.length;i++){
if(items[i].UserId!=null && items[i].UserId!=undefined)
UserIdStr+=items[i].UserId;
if(items[i].PageType!=null && items[i].PageType!=undefined)
PageTypeStr+=items[i].PageType;
}
result.push({UserId:UserIdStr,PageType:PageTypeStr});
return result;
}
Query
--first query
WITH f AS (
SELECT
e.context.data.eventTime as EventDateTime,
e.context.application.version as AppVersion,
e.event as flatEvent,
UDF.coalesce(e.[context].[custom].[dimensions]) as flatDimensions
FROM [ios] e
)
--second query
SELECT flatEvent.ArrayValue.name as Event,
f.EventDateTime,
f.AppVersion,
flatDimension.ArrayValue.UserId,
flatDimension.ArrayValue.PageType,
SUM(flatEvent.ArrayValue.count) as CountA
FROM f
CROSS APPLY GetArrayElements(f.[flatEvent]) as flatEvent
OUTER APPLY GetArrayElements(f.[flatDimensions]) as flatDimension
GROUP BY SlidingWindow(minute, 1),
flatEvent.ArrayValue.name,
f.EventDateTime,
f.AppVersion,
flatDimension.ArrayValue.UserId,
flatDimension.ArrayValue.PageType
TEST RESULT

How to MDX query for last 12 weeks in my time dimension?

I have a bunch of question on MDX queries because i just started to learn about OLAP and SSRS report with SQL report builder.
First question is, could you please give me a link to the best sites that have a tutorial on MDX Queries..
Second, i already deploy a sales cubes.. What is the best way to pass parameter to the query? I mean how if i would like to query my sales for last 12 weeks automatically without using parameters (auto generate if now is in week 30 than it shows the data from week 18 to 30, and so on)..
here is my query that generated automatically from designer:
SELECT NON EMPTY { [Measures].[Total Stick] } ON COLUMNS,
NON EMPTY
{
( [PALAPA Location].[LocationCode].[LocationCode].AllMembers * [PALAPA Fact Sales].[Year].[Year].AllMembers * [PALAPA Fact Sales].[Week].[Week].AllMembers )
} Dimension Properties MEMBER_CAPTION,
MEMBER_UNIQUE_NAME ON ROWS
FROM (
SELECT (
{ [Time_Dim].[Week].&[2015-06-21T00:00:00], [Time_Dim].[Week].&[2015-06-28T00:00:00], [Time_Dim].[Week].&[2015-07-05T00:00:00], [Time_Dim].[Week].&[2015-07-12T00:00:00], [Time_Dim].[Week].&[2015-07-19T00:00:00] } ) ON COLUMNS
FROM (
SELECT ( { [Time_Dim].[Year].&[2015-01-01T00:00:00] } ) ON COLUMNS
FROM [PALAPA_DSV]
)
)
WHERE ( [Time_Dim].[Year].&[2015-01-01T00:00:00], [Time_Dim].[Week].CurrentMember ) CELL Properties Value,
BACK_COLOR,
FORE_COLOR,
FORMATTED_VALUE,
FORMAT_STRING,
FONT_NAME,
FONT_SIZE,
FONT_FLAGS
Third question, i would like to set the default values at SQL Report builder parameter (Week dimension) with this code :
=”[TP DIM CALENDAR].[Date].&[” + Format(CDate(Parameters!FromParameter.Value),”yyyy-MM-dd”) +
“T00:00:00]”
But why it didnt work when i run the report? The parameter value is blank..
Thanks for your help !
Please have a look at these mdx functions
StrToMember
https://msdn.microsoft.com/en-us/library/ms146022.aspx
StrToSet
https://msdn.microsoft.com/en-us/library/ms144782.aspx
These and several other StrTo.. functions are used pretty extensively for passing in parameters.
In your example you need to wrap the whole string in something like this:
strToMember(
"[TP DIM CALENDAR].[Date].&[" +
Format(CDate(Parameters!FromParameter.Value),"yyyy-MM-dd") +
"T00:00:00]"
)
Found the solution here :
http://www.msbitips.com/?p=4
Thanks for your help whytheq :)

MDX - Retrieving a level of members currently used in where clause

I have a simple data cube with organization structure hierarchy defined. In my calculations inside the cube I would like to have different calculations depending on which level of organization items is currently used in WHERE clause in MDX query.
So let's say that I have 5 levels of organization structure, and for the last level (store level) I would like to change the way that calculation is being made using expression for instance:
IIF([Organization Structure].[Parent Id].LEVEL IS
[Organization Structure].[Parent Id].[Level 05], 'THIS IS STORE', 'THIS IS NOT')
This in Visual Studio browser result in something that we actually want:
and same for using MDX Query like:
SELECT { [Measures].[TEST] } ON COLUMNS
FROM [DataCubeName]
WHERE
{
[Organization Structure].[Parent Id].&[123]
}
Problem starts, when we want to use more than one organization structure item in WHERE clause. It is allowed to have items in this clause from the same level only, and I still would like to know which level is it, but of course when we add second item to WHERE like so:
SELECT { [Measures].[TEST] } ON COLUMNS
FROM [DataCubeName]
WHERE
{
[Organization Structure].[Parent Id].&[123],
[Organization Structure].[Parent Id].&[124]
}
I get error that "currentmember failed because the coordinate for the attribute contains a set".
That's why in my expression I have tried to use ITEM(0) function in many different configurations, but I just couldn't find a way to use it on a set of items that are currently used in WHERE clause... So the big question is:
How to get a set of items, that are listed in WHERE clause that is currently being executed so I can use Item(0) on that set, or is there any other way of retrieving Level of currently selected items knowing that they must be the same level?
Using Currentmember combined with set in the where clause is potentially problematic.
See this post from chris Webb: http://blog.crossjoin.co.uk/2009/08/08/sets-in-the-where-clause-and-autoexists/
Here is a possible workaround for your situation: you can try adapting to your curcumstance.
WITH
MEMBER [Measures].[x] AS
IIF
(
(existing [Geography].[Geography].[State-Province].members).item(0).Level
IS
[Geography].[Geography].[State-Province]
,'THIS IS state'
,'THIS IS NOT'
)
SELECT
{[Measures].[x]} ON COLUMNS
FROM [Adventure Works]
WHERE
(
{[Geography].[Geography].[State-Province].&[77]&[FR],
[Geography].[Geography].[State-Province].&[59]&[FR]}
);
Expanding the above to prove it works:
WITH
MEMBER [Measures].[x] AS
IIF
(
(EXISTING
[Geography].[Geography].[State-Province].MEMBERS).Item(0).Level
IS
[Geography].[Geography].[State-Province]
,'THIS IS state'
,'THIS IS NOT'
)
MEMBER [Measures].[proof] AS
(EXISTING
[Geography].[Geography].[State-Province].MEMBERS).Item(0).Member_Caption
MEMBER [Measures].[proof2] AS
(EXISTING
[Geography].[Geography].[State-Province].MEMBERS).Count
SELECT
{
[Measures].[x]
,[Measures].[proof]
,[Measures].[proof2]
} ON COLUMNS
FROM [Adventure Works]
WHERE
{
[Geography].[Geography].[State-Province].&[77]&[FR]
,[Geography].[Geography].[State-Province].&[59]&[FR]
};
Results in the following:
So your expression could become something like the following:
IIF
(
(EXISTING
[Organization Structure].[Parent Id].MEMBERS).Item(0).Level
IS
[Organization Structure].[Parent Id].[Level 05]
,'THIS IS STORE'
,'THIS IS NOT'
)

Parse json arrays using HIVE

I have many json arrays stored in a table (jt) that looks like this:
[{"ts":1403781896,"id":14,"log":"show"},{"ts":1403781896,"id":14,"log":"start"}]
[{"ts":1403781911,"id":14,"log":"press"},{"ts":1403781911,"id":14,"log":"press"}]
Each array is a record.
I would like to parse this table in order to get a new table (logs) with 3 fields: ts, id, log.
I tried to use the get_json_object method, but it seems that method is not compatible with json arrays because I only get null values.
This is the code I have tested:
CREATE TABLE logs AS
SELECT get_json_object(jt.value, '$.ts') AS ts,
get_json_object(jt.value, '$.id') AS id,
get_json_object(jt.value, '$.log') AS log
FROM jt;
I tried to use other functions but they seem really complicated.
Thank you! :)
Update!
I solved my issue by performing a regexp:
CREATE TABLE jt_reg AS
select regexp_replace(regexp_replace(value,'\\}\\,\\{','\\}\\\n\\{'),'\\[|\\]','') as valuereg from jt;
CREATE TABLE logs AS
SELECT get_json_object(jt_reg.valuereg, '$.ts') AS ts,
get_json_object(jt_reg.valuereg, '$.id') AS id,
get_json_object(jt_reg.valuereg, '$.log') AS log
FROM ams_json_reg;
I just ran into this problem, with the JSON array stored as a string in the hive table.
The solution is a bit hacky and ugly, but it works and doesn't require serdes or external UDFs
SELECT
get_json_object(single_json_table.single_json, '$.ts') AS ts,
get_json_object(single_json_table.single_json, '$.id') AS id,
get_json_object(single_json_table.single_json, '$.log') AS log
FROM ( SELECT explode (
split(regexp_replace(substr(json_array_col, 2, length(json_array_col)-2),
'"}","', '"}",,,,"'), ',,,,')
) FROM src_table) single_json_table;
I broke the lines up so that it would be a little easier to read.
I'm using substr() to strip the first and last characters, removing [ and ] . I'm then using regex_replace to match the separator between records in the json array and adding or changing the separator to be something unique that can then be used easily with split() to turn the string into a hive array of json objects which can then be used with explode() as described in the previous solution.
Note, the separator regex used here ( "}"," ) wouldn't work with the original data set...the regex would have to be ( "},\{" ) and the replacement would then need to be "},,,,{" eg..
split(regexp_replace(substr(json_array_col, 2, length(json_array_col)-2),
'"},\\{"', '"},,,,{"'), ',,,,')
Use explode() function
hive (default)> CREATE TABLE logs AS
> SELECT get_json_object(single_json_table.single_json, '$.ts') AS ts,
> get_json_object(single_json_table.single_json, '$.id') AS id,
> get_json_object(single_json_table.single_json, '$.log') AS log
> FROM
> (SELECT explode(json_array_col) as single_json FROM jt) single_json_table ;
Automatically selecting local only mode for query
Total MapReduce jobs = 3
Launching Job 1 out of 3
Number of reduce tasks is set to 0 since there's no reduce operator
hive (default)> select * from logs;
OK
ts id log
1403781896 14 show
1403781896 14 start
1403781911 14 press
1403781911 14 press
Time taken: 0.118 seconds, Fetched: 4 row(s)
hive (default)>
where json_array_col is column in jt which holds your array of jsons.
hive (default)> select json_array_col from jt;
json_array_col
["{"ts":1403781896,"id":14,"log":"show"}","{"ts":1403781896,"id":14,"log":"start"}"]
["{"ts":1403781911,"id":14,"log":"press"}","{"ts":1403781911,"id":14,"log":"press"}"]
because get_json_object doesn't support json array string, so you can concat to a json object, like this:
SELECT
get_json_object(concat(concat('{"root":', jt.value), '}'), '$.root')
FROM jt;

Error: The MDX function CURRENTMEMBER failed because the coordinate for the attribute contains a set

How to handle this error:
The MDX function CURRENTMEMBER failed because the coordinate for the attribute contains a set.
when executing MDX query:
SELECT (
{ [Measures].[Amount]}
)ON COLUMNS,
(
[OrganizationUnits].[Description].[Description].MEMBERS,
[OrganizationUnits].[IsCURRENT].[IsCURRENT]
) ON ROWS
FROM
(SELECT [OrganizationUnits].[Description] ON 0
FROM
[CubeName]
WHERE(
{[OrganizationUnits].[Description].&[Unit1],[OrganizationUnits].[Description].&[Unit2]}
)
)
Thanks!!
You seem to have a calculated member in your cube that uses the .CurrentMember, probably something like [OrganizationUnits].[Description].CurrentMember. This causes an error with sets having more than one member in the where condition, like you have it with
WHERE(
{[OrganizationUnits].[Description].&[Unit1],[OrganizationUnits].[Description].&[Unit2]}
)
The following article - as well as the one it references at the top - contain some suggestions how to work around this type of problem: https://web.archive.org/web/20170514194410/http://sqlblog.com/blogs/mosha/archive/2007/01/13/multiselect-friendly-mdx-for-calculations-looking-at-current-coordinate.aspx

Resources