Do You Want to Learn SQL?

Take our free eight day course, where I'll teach you in simple to understand English all you need to get started learning SQL.

-
DAYS
-
HOURS
-
MINUTES
-
SECONDS

Free Beginners SQL Course!

Use hierarchyid to query Hierarchical data

·

·

In this SQL minute we’ll look at how you can use hierarchyid to query hierarchy data.  This is a two-part article.  In this article we look at how to do one query to get portion of the hierarchy.  Next week, we will look to see how to query the entire tree.

For this problem we will use the AdventureWorks database.

Who works for JoLynn?

Hidden in the Employee table is AdventureWorks’ organizational structure. Though the HRIS specialist is adept at basic SELECT and JOINS, she is having a hard time finding out who reports to JoLynn Dobney.

Can you help her by writing some T-SQL to find all of JoLynn’s direct reports? For each direct report, output their JobTitle, First Name, and Last Name.

Write your query, and then look below to see how I did it!

Answer using hierarchyid functions.

Before we get to the answer lets get some terminology under our belt.  Hierarchical data can be though of as a tree.  In the diagram below you’ll see an organization chart.  The tree is upside down, as it “branches” down the page, instead of up to the sky.

Notice that the tree starts with a Root, this is the tree’s beginning.

tree image - hierarchyid

Also, each node in the tree is connected to zero or more other nodes.  Any node can be considered a parent.  Any nodes branching from it are children.

Using the family tree metaphor, the parent has decedents, which are the children.  And the children have ancestors, which are parents and grandparents…

I’m old school, so most of the hierarchical data I’m used to using in a database is in the form of a parentID column being the foreign key to a primary key.

For example, the EmployeeID is the primary key and the Manager ID the parent.

parent child alternative to hierarchyid

In the adventure works database this is done differently.  Here the reporting structure is conveyed using the hierarchyid type.  This type provides a means to relate the parent-child relationships using one field.

HierarchyID Type built-in Functions

A hierarchyid value is a hash value.  Its value is in the built-in function we can use to navigate the hierarchy, such as:

  • GetAncestor – Return the hierarchyid of the parent of the current row.
  • GetDescendant – Return the hierarchyid of a child of the current row.
  • GetRoot – Return the top (root) of the hierarchy.

To solve this problem I’m going to use the GetAncestor function to return the parent hierarchyid.  The idea is to first get the hierarchyid for JoLynn, and then return all records whose ancestor hierarchyid matches hers.

Below is the code I used to write the query. In the first part we get JoLynn’s hierarchyid.

In the second part we get hierarchyid of an employee’s boss. If it matches JoLynn’s hierarchyid, then we keep the row in our result…

--get direct reports  
--Part 1:  Find JoLynn’s hierarchyID in Employee Database
DECLARE @CurrentEmployee HIERARCHYID;
SELECT @CurrentEmployee=OrganizationNode
FROM   HumanResources.Employee E
       INNER JOIN Person.Person P ON
E.BusinessEntityID = P.BusinessEntityID
WHERE  P.FirstName ='JoLynn' AND P.LastName ='Dobney';

--Part 2:  Find all direct reports for JoLynn
SELECT E.JobTitle,
       P.FirstName,
       P.LastName
FROM   HumanResources.Employee E
       INNER JOIN Person.Person P ON
E.BusinessEntityID = P.BusinessEntityID
WHERE  OrganizationNode.GetAncestor(1)= @CurrentEmployee;

Here is another way to write the same code using a subquery!

SELECT E.JobTitle,
       P.FirstName,
       P.LastName
FROM   HumanResources.Employee E
       INNER JOIN Person.Person P ON
E.BusinessEntityID = P.BusinessEntityID
WHERE  OrganizationNode.GetAncestor(1)=
(SELECT OrganizationNode
FROM   HumanResources.Employee E
       INNER JOIN Person.Person P ON
E.BusinessEntityID = P.BusinessEntityID
WHERE  P.FirstName ='JoLynn' AND P.LastName ='Dobney
')

The subquery returns a single value, the same as returned in the first step where we saved it to @currentEmployee.

Let me know if you have another way to solve the problem. Just post it in the comments. Also, if you want to get on my list to get sent a new problem to solve each week, don’t forget to SQL Practice Work book.

Related Reading

SQL Joins – The Ultimate Guide

Recursive Common Table Expressions (CTE)

2 responses to “Use hierarchyid to query Hierarchical data”
  1. Sandeep

    Unable to download the SQL practice work book. Not sure why.

    1. Hi Sandeep,

      I just checked, and the link provided in the email is working. It is a PDF, so make sure you’re able to download or view that doc type.

      Kris.

Leave a Reply

Your email address will not be published. Required fields are marked *

This site uses Akismet to reduce spam. Learn how your comment data is processed.

More from the blog


MySQL PostgreSQL SQLite SQL Server