Home > SQL Server Tips > Data Warehousing and Business Intelligence > Parent-child dimensions in SQL Server 2005 with Analysis Services MDX
SQL Server Tips:
EMAIL THIS
 TIPS & NEWSLETTERS TOPICS 

DATA WAREHOUSING AND BUSINESS INTELLIGENCE

Parent-child dimensions in SQL Server 2005 with Analysis Services MDX


Baya Pavliashvili
09.23.2008
Rating: -4.83- (out of 5)


Expert advice on database administration
Digg This!    StumbleUpon Toolbar StumbleUpon    Bookmark with Delicious Del.icio.us    Add to Google


Parent-child dimensions in SQL Server 2005 solve the common business problem of defining records in a particular table related to other records within the same table. For example, each employee has a direct supervisor, who in turn has her own supervisor, all the way up to the enterprise owner or the chief executive officer. Similarly, if your business serves institutional customers, then each entity could be a "child" of another larger organization or division. So the smallest customer could be a sub-department, which rolls up to a department, group, market, region, division and finally the full organization.

Your reports and analytical views will often need to group such related records together. A common example would be to examine the manager's sales along with the sales of all employees who work for this manager.

Handling such recursive relationships in SQL can be tricky because each record can have a different number of parent records. Sometimes this condition is referred to as unbalanced or ragged hierarchy. For example, let's review a very small "employees" table:

CREATE TABLE [dbo].[Employees](
[EmployeeID] [int] IDENTITY(1,1) NOT NULL,
[Name] [nvarchar](20) NOT NULL,
[Title] [nvarchar](30) NULL,
[ReportsTo] [int] NULL
CONSTRAINT [PK_Employees] PRIMARY KEY CLUSTERED
(
[EmployeeID] ASC
)
)
ALTER TABLE [dbo].[Employees] ADD
CONSTRAINT [FK_Employees_Employees1] FOREIGN KEY([ReportsTo])
REFERENCES [dbo].[Employees] ([EmployeeID])

Let's say we only have four records in this table, as follows:

Employee ID Name Title Reports To
2 Andrew President, Sales NULL
3 Janet sr. sales rep 2
4 Margaret sales rep 3
5 Steven Intern 4

In this fictitious organization, Andrew is the "big dog" and his record has no parent because he doesn't have a direct supervisor. Janet's record has one parent, Margaret's record has two and Steven's has three.

How would you retrieve an organizational chart from your employee table? Let's say we want to retrieve records for Steven and his immediate supervisor. That's relatively easy:

SELECT
a.EmployeeID,
a.Name,
a.Title,
b.Name AS SupervisorName,
a.ReportsTo
FROM Employees a
LEFT JOIN Employees b ON a.ReportsTo = b.EmployeeID
WHERE a.EmployeeID = 5

But this only gives us Steven and Margaret. To get the next person in the hierarchy, we'd have to join the Employees table to itself, twice. To get the full hierarchy we'd need three joins, like the following:

SELECT ...


Digg This!    StumbleUpon Toolbar StumbleUpon    Bookmark with Delicious Del.icio.us    Add to Google



RELATED CONTENT
SQL Server Business Intelligence (BI) and Data Warehousing
Are data warehouses made for the cloud?
Q&A: Business intelligence gets a facelift in SQL Server 2008 R2
Project Gemini gets a new name, Madison earns buzz
Speed up reports in SQL Server Reporting Services with caching
Data Transformation Services vs. SSIS: The key differences
Using package configurations in SQL Server Integration Services (SSIS)
How SQL Server 2008 components impact SharePoint implementations
Achieving high availability and disaster recovery with SharePoint databases
Recommended practices for SQL Server Analysis Services aggregations
SQL Server Reporting Services 2008 offers faster speeds, new variations

Microsoft SQL Server 2005 (Yukon)
End of life comes for SQL Server 2005 SP2, 2008
SQL Server Reporting Services Fast Guide
SQL Server Service Broker Tutorial and Reference Guide
Tips for tuning SQL Server 2005 to improve reporting performance
SQL Server consolidation: Why it's an optimization technique
Enforcing data integrity in a SQL Server database
SSIS error message due to installation problem on SQL Server 2005
Should you upgrade to SQL Server 2005 or SQL Server 2008?
Basics for working with DATETIME and SMALLDATETIME in SQL Server 2005
How to configure Database Mail in SQL Server 2005 to send mail
Microsoft SQL Server 2005 (Yukon) Research

Microsoft SQL Server Performance Monitoring and Tuning
SQL Server Mailbag: CALs, witnesses and unwanted changes
SQL Server Mailbag: Data restoration and DB property management
Working with IntelliSense in SQL Server 2008 Management Studio
SQL Server Mailbag: Stored procedures, triggers and SSRS reports
Troubleshooting Distributed Transaction Coordinator errors in SQL Server
Clearing the Windows page file and its effect on server performance
Optimizing SQL Server indexes –- even when they're not your indexes
Performance implications of transaction log autogrowth in SQL Server
The short course on how SQL Server really works
Determining the source of full transaction logs in SQL Server

RELATED GLOSSARY TERMS
Terms from Whatis.com − the technology online dictionary
data aggregation  (SearchSQLServer.com)
data preprocessing  (SearchSQLServer.com)
data warehouse  (SearchSQLServer.com)
FileMaker  (SearchSQLServer.com)
GIS  (SearchSQLServer.com)
MOLAP  (SearchSQLServer.com)
pivot table  (SearchSQLServer.com)
Quiz: SQL Server 2000  (SearchSQLServer.com)
SQL  (SearchSQLServer.com)
T-SQL  (SearchSQLServer.com)

RELATED RESOURCES
2020software.com, trial software downloads for accounting software, ERP software, CRM software and business software systems
Search Bitpipe.com for the latest white papers and business webcasts
Whatis.com, the online computer dictionary


a.EmployeeID,
a.Name,
a.Title,
b.Name AS SupervisorName,
c.Name AS NextSupervisorName,
d.Name AS TopSupervisorName
FROM Employees a
LEFT JOIN Employees b ON a.ReportsTo = b.EmployeeID
LEFT JOIN Employees c ON b.ReportsTo = c.EmployeeID
LEFT JOIN Employees d ON c.ReportsTo = d.EmployeeID
WHERE a.EmployeeID = 5

Result:

EmployeeID Name Title Supervisor NextSupervisor TopSupervisor
5 Steven Intern Margaret Janet Andrew

This works OK on a fictitious company sample with a handful of employees, but it should be apparent that retrieving a hierarchy with recursive relationships with SQL can get difficult to manage very quickly. The query becomes even more cumbersome if we want to retrieve the sales of Steven along with each of his manager's sales. For each manager, we should include her sales along with sales of her subordinates:

SELECT
(SELECT COUNT(*) FROM employees a1
INNER JOIN orders b ON a1.employeeid = b.employeeid
WHERE a1.employeeid = a.employeeid) AS [steven's sales],
(SELECT COUNT(*) FROM employees a1
INNER JOIN orders b ON a1.employeeid = b.employeeid
WHERE a1.employeeid = a2.employeeid
OR a1.employeeid = a.employeeid) AS [margaret's sales],
(SELECT COUNT(*) FROM employees a1
INNER JOIN orders b ON a1.employeeid = b.employeeid
WHERE a1.employeeid = a3.employeeid
OR a1.employeeid = a.employeeid
OR a1.employeeid = a2.employeeid
OR a1.employeeid = a3.employeeid) AS [janet's sales],
(SELECT COUNT(*) FROM employees a1
INNER JOIN orders b ON a1.employeeid = b.employeeid
WHERE a1.employeeid = a4.employeeid
OR a1.employeeid = a.employeeid
OR a1.employeeid = a2.employeeid
OR a1.employeeid = a3.employeeid
OR a1.employeeid = a4.employeeid) AS [andrew's sales]
FROM employees a INNER JOIN employees a2
ON a.reportsto = a2.employeeid
INNER JOIN employees a3 ON a2.reportsto=a3.employeeid
INNER JOIN employees a4 ON a3.reportsto=a4.employeeid
WHERE a.employeeid = 5

Result:

Steven's sales Margaret's sales Janet's sales Andrew's sales
42 198 325 421

You can easily implement this type of relationship with a parent-child dimension using Analysis Services MDX.

You don't have to make any changes to your relational table in order to create a parent-child dimension. Simply follow the dimension wizard screens, much like designing any other regular dimension. The wizard automatically detects the recursive relationship if you have specified primary key and foreign key constraints within your relational dimension. Alternatively you could also define logical relationships within your data source view.

In our example, the column "ReportsTo" references the "EmployeeID" column. Once you have created a parent-child dimension, you should set the MembersWithData property of your attribute hierarchy to NonLeafDataHidden. This property determines whether to display non-leaf (meaning members not on the bottom level of the parent-child hierarchy) attribute members. By default the parent-child hierarchy is given the same name as the dimension table. I renamed the hierarchy to "org_chart" for clarity.

Once you process your dimension, the employees will show up as follows (Figure 1):

[IMAGE]


Figure 1: Hierarchy results after processing dimensions in Analysis Services MDX.

If you had left MembersWithData at its default value (NonLeafDataVisible), you'd see the values of Andrew under Andrew, Janet under Janet and so on. Indeed, if you wanted to see Andrew's orders without adding orders of his subordinate employees to his total you would choose NonLeafDataVisible.

With MDX, getting the organizational structure starting from Steven involves executing a very simple query, as follows:

SELECT ASCENDANTS(employees.org_chart.steven) ON 0,
{measures.[orders count]} ON 1
FROM [cube name]

Results:

Steven Margaret Janet Andrew All
Orders Count 42 198 325 421 421

Similarly, to retrieve all employees of Janet you could issue the following MDX query:

SELECT
DESCENDANTS(employees.org_chart.Janet) ON 0,
{measures.[orders count]} ON 1
FROM [cube name]

Results:

Janet Margaret Steven
Orders Count 325 198 42

What if you wanted to see Janet's sales excluding the sales of employees who report to her? You'd use the attribute hierarchy associated with the dimension key, as opposed to the parent-child hierarchy, as follows:

SELECT
employees.employees.Janet ON 0,
{measures.[orders count]} ON 1
FROM [cube name]

Results:

Janet
Orders Count 127

Alternatively, you could exploit DataMember function to retrieve the sales associated only with Janet while querying the parent-child hierarchy, as follows:

SELECT
employees.org_chart.Janet.DataMember ON 0,
{measures.[orders count]} ON 1
FROM [cube name]

Parent-child dimensions can handle any number of levels, even though you only define a single level. Unlike SQL Server you don't have to worry about adding variable number of joins to your MDX statements in order to retrieve parents (or children) of a particular member.

Parent-child hierarchy promotes members to the top level based on the value of the RootMemberIF property. In the example shown earlier in this tip, Andrew appears on the top level of the hierarchy because the value of ReportsTo column is null. Let's see what happens if we update the row for Margaret's so that employee id and reports to column have the same value, equal to 4. Now both Margaret and Andrew appear on top of the hierarchy (Figure 2).

[IMAGE]


Figure 2: Results after updating rows so employee id and reports to column have the same value, equal to 4.

The default value of the RootMemberIF property is ParentIsBlankSelforMissing. This value indicates that each member whose record has NULL or blank values in the ReportsTo column, as well as those whose employee id and reports to columns have identical values, will be promoted to the top level of the hierarchy. Alternatively, you could choose ParentIsBlank, ParentIsMissing or ParentIsSelf values for this property, depending on your needs.

Another interesting property of parent-child hierarchies is NamingTemplate. In a regular hierarchy, each level is named after the attribute it is based on. For example, in a date hierarchy you would have levels of year, quarter, month, etc. Since you only define a single attribute for the parent-child hierarchy, it cannot inherit the name for various levels based on attribute names. Instead, it assigns an ordinal number to levels. By default, levels would be called Level 01, Level 02, Level 03 and so on. You can override this default behavior and provide a more descriptive naming template. For example, in our sales scenario we could call levels Salesperson01, Salesperson02, etc. To do so, set the value of NamingTemplate property to "Salesperson *".

ABOUT THE AUTHOR:   

[IMAGE]Baya Pavliashvili is a database consultant helping his customers develop highly available and scalable applications with SQL Server and Analysis Services. Throughout his career he has managed database administrator teams and databases of terabyte caliber. Baya's primary areas of expertise are performance tuning, replication and data warehousing. He can be reached at baya@bayasqlconsulting.com.


MEMBER FEEDBACK TO THIS TIP

Do you have a comment on this tip? Let us know.


Rate this Tip
To rate tips, you must be a member of SearchSQLServer.com.
Register now to start rating these tips. Log in if you are already a member.




DISCLAIMER: Our Tips Exchange is a forum for you to share technical advice and expertise with your peers and to learn from other enterprise IT professionals. TechTarget provides the infrastructure to facilitate this sharing of information. However, we cannot guarantee the accuracy or validity of the material submitted. You agree that your use of the Ask The Expert services and your reliance on any questions, answers, information or other materials received through this Web site is at your own risk.



SQL Server Development - .NET, C#, T-SQL, Visual Basic
HomeNewsTopicsITKnowledge ExchangeTipsAsk the ExpertsMultimediaWhite PapersIT Downloads
About Us  |  Contact Us  |  For Advertisers  |  For Business Partners  |  Site Index  |  RSS
SEARCH 
TechTarget provides technology professionals with the information they need to perform their jobs - from developing strategy, to making cost-effective purchase decisions and managing their organizations' technology projects - with its network of technology-specific websites, events and online magazines.

TechTarget Corporate Web Site  |  Media Kits  |  Site Map




All Rights Reserved, Copyright 2005 - 2009, TechTarget | Read our Privacy Policy
  TechTarget - The IT Media ROI Experts