Beginning with the fifth article of the MDX Essentials series, Member Functions: The "Family" Functions, we began an examination of the "family functions," stating that the functions and operators that compose this group (for the purposes of this set of articles) include:

  • .Parent
  • .Children
  • Ancestor()
  • Cousin()
  • .FirstChild
  • .LastChild
  • .FirstSibling
  • .LastSibling

We mentioned that the "family" metaphor is appropriate to this group, because these functions perform operations on dimensions, hierarchies and levels in a manner that simulates movement about a "family tree." As we stated in Article Five, our focus in this group of three articles is primarily a subset of the member functions, although other "family"-like functions are available that return sets.

This lesson will include an introduction to the .Cousin() function, with:

  • an examination of the syntax that surrounds its use;
  • an illustrative example of its use in a practice exercise;
  • a brief discussion of the MDX results we obtain in the practice example.

As we discussed in Lessons Five and Six, many member functions, particularly those of the "family" group, allow us to perform operations based upon a member's relative position, either up ("above" the member upon which the function is being performed) or down ("below" the member upon which the function is being performed) a dimensional hierarchy. In this sense, as we previously observed, there are two general groups (from the perspective of the result datasets they return) to which the members of the "family" functions belong. One group works within a "vertical" scope, traveling up or down between hierarchical levels, while the second group operates within a "horizontal" scope ("across" versus "up and down") of the hierarchy involved, while traveling within the same level of the hierarchy.

The Cousin() Function

As we have shown in previous articles, the capability to perform operations within the vertical and horizontal scopes of the hierarchy can mean more efficient, simpler MDX queries. The Cousin() function belongs to the latter of the two general groups, as it returns a member that is "parallel" in position under a given ancestor member, as we will see. We'll take a look at the Cousin() function in this article, to obtain an appreciation for its capabilities.


As we will observe, the Cousin() function returns the child member that occupies the same relative position under a parent member as the source member (under its own respective parent) that is specified. The operation of the function is based upon the order and position of members within levels. Let's say that two dimensions exist, in which dimension one has three levels, and dimension two has five levels. In this case, the cousin of the second level of dimension one is the second level of the dimension two.

An illustration of this concept might be helpful in providing a visual platform upon which to understand the workings of the function. As in previous articles, we'll consider the Time dimension for this illustration because we all understand the Time hierarchy, and can therefore focus on the core concept instead of the structure of the hierarchy we rely upon as an example. The illustration to which I refer appears below.

Illustration 1: Time Dimension Hierarchy, Showing an Example Cousin Relationship.

We will rely heavily upon the Time dimension in illustrating the syntax and use of the Cousin() function for another related reason: the Time dimension, composed of years, quarters, months, and so forth, works well with Cousin(), because, in most cases, an identical number of descendant members reside under any given ancestor. This scenario provides an excellent basis for using the Cousin() function. There are certainly situations where even typical Time hierarchies are not identical (an example would be the cousin of May 31 in September: September has only thirty days, so there is no valid cousin for May 31 in this instance. But for the most part, the Time dimension is about as predictable as it gets, with regard to consistency in arrangement.


The Cousin() function is written in standard function format, which is to say Function(Arguments). The parentheses enclose the arguments, in this case the member that the function specifies (the member for which we seek to return the cousin), and the ancestor member upon whose "lineage" we wish to find the cousin member. The two members within the argument are separated by a comma.

Let's look at the syntax in the following example:

	{Cousin([Time].[1997].[Q1],[Time].[1998])} ON COLUMNS
	WHERE ([Measures].[Amount])

The result dataset returned would appear as shown in Illustration 2 below:

Illustration 2: Example Result Dataset from Using the Cousin() Function

As we can see above, the Cousin() function within the example yields the member [1998].Q1. In the Budget cube, the 1997 and 1998 levels both contain Q1, Q2, Q3, and Q4. [1998].Q1 is returned because it occupies the same relative position (the first child position) within the 1998 Year level as is occupied by Q1 (again, the first child) in Year 1997.

A graphic view of the Time hierarchy for the source member ([Time].[1997].[Q1]) within the function above will make the illustration more meaningful. In Illustration 3 below, we see that Q1 is a member of the Quarters sublevel of the 1997 Year level, within the Time dimension. The order of the members within the database determines the status of Q1 as "first;" Q1 is the first child member of the 1997 Year level. Therefore, when we specify in the second part of the function that we want the "same relative position for the 1998 level of the Time hierarchy," the first child member (which happens again to be Q1, in this example) is returned.

Illustration 3 displays the foregoing graphically.

Illustration 3: Graphical Results of Using the Cousin() Function

In the simple example above, we can easily see that the cousin member is Q1 of 1998.