简体   繁体   中英

Filter on Multiple DateRanges in MDX

Assuming that I have a table that looks like

ID | EntryDate  | ExitDate   | LastSeen   | Sex
---|------------|------------|----------------
1  | 2000-01-23 | 2015-01-18 | 2013-08-01 | M
2  | 2008-01-13 | null       | 2012-06-25 | F
3  | 2014-01-09 | 2014-12-21 | 2014-09-12 | M

I have Created Measures and Dimensions as [Measures].[People] as Count(ID) and have 3 unique Date Dimensions [EntryDate],[ExitDate],[LastSeenDate] with [Day] Level which is represented in format of 'YYYYMMDD' (eg:20151231)

The MDX I want to write is to count the number of People Who had an entry before Jan 1 2014, Last Seen after Jan 1 2013, and also have an exit date after Jan 1 2013

If I were to write this as an sql the syntax would be

Select count(ID) from table where entryDate < 20140101 and exitDate > 20130101 and lastseenDate > 20130101;

My First Attempt was to Write MDX as

With
Set [EnrolDateRange] As Filter([EnrolDate].[Day].Children,[Enrol Date].[Day].CurrentMember.Name < '20140101')
Set [LastSeenDateRange] As Filter([LastSeenDate].[Day].Children,[LastSeen Date].[Day].CurrentMember.Name > '20130101')
Set [ExitDateRange] As Filter([ExitDate].[Day].Children,[ExitDate].[Day].CurrentMember.Name > '20130101')
MEMBER [Measures].[N1] As Aggregate ([EnrolDateRange],[Measures].[People])
MEMBER [Measures].[N2] As Aggregate ([LastSeenDateRange],[Measures].[People])
MEMBER [Measures].[N3] As Aggregate ([ExitDateRange],[Measures].[People])
MEMBER [Measures].[Total] As ([Measures].[N1] + [Measures].[N2] + [Measures].[N3])
Select { [Measures].[Total] } on columns, { [Sex].[Sex].Children } on Rows FROM [Cube]

But the problem here is the total that i get is wrong as the same rows would be aggregated for each condition separately.

The reason I am not able to do cross join on the dates is because I have more that 60 years of data.

Is there any way that the above can be achieved using MDX

Use NULL:(Date) for <= and (Date):NULL for >= .

select [Measures].[People] on 0
from [Cube]
where
(
 {NULL:[EntryDate].[Day].&[20131231]}
 /* not 20140101 because <= */

 ,{[LastSeenDate].[Day].&[20130102]:NULL}
 /* not sure, you mean after including Jan 1st or no */

 ,{[ExitDate].[Day].&[20130102]:NULL} /* the same */
)

One major tip: members in filter have to exist in every dimension.

Eg if there is no [EntryDate].[Day].&[20131231] in this dimension, server substitutes it with NULL and has no idea what dimension is filtered, since another range part is our NULL from query. Result will be NULL at all, be careful.

As for my practice: it's better to add empty members (with no real data) to the dimension than develop another behavior like "if member doesn't exist find first non-empty member on the right/left of it". This won't affect disk space (only dimension data), and performance degradation is very low in comparison with tricky logics.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM