MDX Group & Count - sql-server

I'm having the below MDX Query
WITH
MEMBER Measures.Improvement AS
[Measures].[School Evaluation]
-
(
[Measures].[School Evaluation]
,[Cycle].[Name].CurrentMember.PREVMEMBER
)
MEMBER Measures.PreviousEvaluation AS
(
[Measures].[School Evaluation]
,[Cycle].[Name].CurrentMember.PREVMEMBER
)
SELECT
Measures.Improvement ON COLUMNS,
Filter (
{ [Cycle].[Name].[Name].ALLMEMBERS }
* { [School].[Name En].[Name En].ALLMEMBERS }
, Measures.PreviousEvaluation > 0
AND
[Measures].[School Evaluation] > 0
)
ON ROWS
FROM [SchoolCube];
This code generates the below output
Now what I need is to count the occurrence of Improvement "-2,-1,0,..." across all the schools So I have something like this
How Can I achieve this?
Thanks,

You have to add another dimension "Improvement" that holds possible values for either a fixed range, e.g. -10..+10 or you build the range dynamically based on your data.
Add a second measure group to the cube based on that dimension table and create a measure "Improvement base", that sums the improvement value. This is a helper measure to simplify the following steps.
Now you can create a new calculated measure:
CREATE MEMBER CURRENTCUBE.[Measures].[Count Improvements] AS
SUM(IIF([Measures].[Improvement] = [Measures].[Improvement base], 1, 0));
Maybe you have to scope the All-member of the Improvement dimension to sum the children.

Related

Subtotals with ArrayFormula()

I've created a simple table and trying to split data with subtotals.
A indicates the subtotal lines.
B contains the rows number for previous subtotal. This is just extra field to simplify formulas.
C Contains some amounts.
D Contains subtotals of amounts between previous and current subtotal line.
The subtotal formula has the following view:
=ArrayFormula(
IF($A2:$A; MMULT(
($B2:$B < TRANSPOSE(ROW($A2:$A))) * (TRANSPOSE(ROW($A2:$A)) < ROW($A2:$A));
IF(ISNUMBER(C2:C); C2:C; 0)
); )
)
The problem is that the formula is extrimely slow. Is there a way to make it faster?
Example file:
https://docs.google.com/spreadsheets/d/1HPGeLZfar2s6pIQMVdQ8mIPzNdw2ESqKAwZfo4IicnA/edit?usp=sharing
You could also try this much simpler formula:
=ArrayFormula(
if(B3:B="","",
sumif(row(B3:B),"<="&row(B3:B),C3:C)-
sumif(row(B3:B),"<="&B3:B,C3:C)
)
)
Yes there is
The easier is to remove the blank rows below the data range.
One that might require maintenance, replace open reference like $A2:$A by closed references, i.e. $A2:$A100
One that incresase the formula complexity an volatility, put each open reference inside ARRAY_CONSTRAIN but it's easier to maintain in case that new data rows were added
use the "necessary" range:
=ARRAYFORMULA(IFERROR(IF(A2:A; MMULT((
INDIRECT("B2:B"&MAX(IF(B2:B="";; ROW(B2:B)))) < TRANSPOSE(ROW(
INDIRECT("A2:A"&MAX(IF(A2:A=TRUE; ROW(A2:A); )))))) * (TRANSPOSE(ROW(
INDIRECT("A2:A"&MAX(IF(A2:A=TRUE; ROW(A2:A); ))))) < ROW(
INDIRECT("A2:A"&MAX(IF(A2:A=TRUE; ROW(A2:A); ))))); IF(ISNUMBER(
INDIRECT("C2:C"&MAX(IF(C2:C="";; ROW(C2:C)+1))));
INDIRECT("C2:C"&MAX(IF(C2:C="";; ROW(C2:C)+1))); 0)); )))
this should be way faster...

Missing value of measure (calculated member )

I've got a data warehouse which is underlying database of OLAP cube.
When I run query like that:
SELECT dimS.Attribute2,SUM(fact.LastValue)
FROM FactTable fact
JOIN DimS dimS ON fact.DimSKey = DimS.DimSKey
GROUP BY DimSKey.Attribute2
I can see that all existing Attribute2 at dimS table have corresponding rows at fact table.
On the other hand I've got a calculated measure:
CREATE MEMBER CURRENTCUBE.[MEASURES].[MyMeasure]
AS ([Measures].[FactTable - LastValue]
, [DimS].[S Hierarchy].[All].[Hierarchy SomeName]
, [DimS].[Category].[All]
, [DimS].[Question].CurrentMember
, [CimC].[Status].&[Active]
),DISPLAY_FOLDER='Folder',VISIBLE = 1;
and when running below MDX:
SELECT
{ [Measures].[MyMeasure] } ON COLUMNS,
{ ([Survey].[Attribute2].ALLMEMBERS ) } ON ROWS
FROM [MyCube]
I can see that 2 of Attribute2 have no values (null) assigned to them.
What can cause issue like that (DimS and cube has been just processed fully)?
Found the rootcause.
the reference in MDX definition of calculated measure to [DimS].[S Hierarchy].[All].[Hierarchy SomeName] is another calculated measure where actually we have hardcoded values within dimension hierarchy. And for [Attribute2] this condition is not met.

Checking existence of dimension in MDX

How I can check if one dimension exist on axis in MDX statetment?
I need to check how many time units (days, weeks, months...) exist on axis1 and use it to calculate measure. Here is example, what should happen, I take some dimensions:
days -> [Measures].[A] = [Measures].[B] / number of members in axis 1, from only date dimension (365)
months -> [Measures].[A] = [Measures].[B] / number of members in axis 1, from only date dimension (12)
months, product group -> [Measures].[A] = [Measures].[B] / number of members in axis 1, from only date dimension (12)
So dimension different than date dimension should't affect calcutation. I only need to get count on members from [Date] dimension.
A simple example is counting of days:
With
Member [Measures].[Members on rows] AS
Axis(1).Count
Select
Non Empty [Measures].[Members on rows] on columns,
Non Empty [Date].[Day].[Day].Members on rows
From [Sales]
Where [Date].[Month].[Month].&[201701]
But you'll get only row count, you can't predict what's going on with an axis. Also you may check whether the whole attribute count = the report attribute count:
Count(existing [Date].[Day].[Day].Members) = Count([Date].[Day].[Day].Members)
If it returns true, most likely that means you don't use filter the [Date].[Day] hierarchy within your report.

MATLAB Extract all rows between two variables with a threshold

I have a cell array called BodyData in MATLAB that has around 139 columns and 3500 odd rows of skeletal tracking data.
I need to extract all rows between two string values (these are timestamps when an event happened) that I have
e.g.
BodyData{}=
Column 1 2 3
'10:15:15.332' 'BASE05' ...
...
'10:17:33:230' 'BASE05' ...
The two timestamps should match a value in the array but might also be within a few ms of those in the array e.g.
TimeStamp1 = '10:15:15.560'
TimeStamp2 = '10:17:33.233'
I have several questions!
How can I return an array for all the data between the two string values plus or minus a small threshold of say .100ms?
Also can I also add another condition to say that all str values in column2 must also be the same, otherwise ignore? For example, only return the timestamps between A and B only if 'BASE02'
Many thanks,
The best approach to the first part of your problem is probably to change from strings to numeric date values. In Matlab this can be done quite painlessly with datenum.
For the second part you can just use logical indexing... this is were you put a condition (i.e. that second columns is BASE02) within the indexing expression.
A self-contained example:
% some example data:
BodyData = {'10:15:15.332', 'BASE05', 'foo';...
'10:15:16.332', 'BASE02', 'bar';...
'10:15:17.332', 'BASE05', 'foo';...
'10:15:18.332', 'BASE02', 'foo';...
'10:15:19.332', 'BASE05', 'bar'};
% create column vector of numeric times, and define start/end times
dateValues = datenum(BodyData(:, 1), 'HH:MM:SS.FFF');
startTime = datenum('10:15:16.100', 'HH:MM:SS.FFF');
endTime = datenum('10:15:18.500', 'HH:MM:SS.FFF');
% select data in range, and where second column is 'BASE02'
BodyData(dateValues > startTime & dateValues < endTime & strcmp(BodyData(:, 2), 'BASE02'), :)
Returns:
ans =
'10:15:16.332' 'BASE02' 'bar'
'10:15:18.332' 'BASE02' 'foo'
References: datenum manual page, matlab help page on logical indexing.

Sum of cost amount calculation

I have attached the screenshot. Most probably that the image itself will explain my logic. Let me paste the code I have used in the fields. Product Info1 field which hold Y & N.
RemainingCosu2=If(Invoice Line Items::Product Info1 = GetAsText ("N"); Sum(Cost Total) - Invoice Line Items::VendPaid_total;0)
RemainingCosu1=If(Vendor Status="Partly Paid"; RemainingCosu2; 0)
What should I do to fix this issue?. Please check the screenshot:
Filemaker has no SumIf() function. You need to create a calculation field in the LineItems table, along the lines of:
If ( Paid = "N" ; Cost )
then sum this field at the invoice level (and/or summarize it at the LineItems table itself), instead of the Cost field.
--
BTW, it is much more convenient to define Boolean (yes/no) fields as Number and use the values of 1 for True, 0 (or empty) for False. Then the calculation can be simply:
If ( not Paid ; Cost )

Resources