programming4us
programming4us
DATABASE

SQL Server 2012 : Querying Hierarchical Tables - The IsDescendantOf Method

- How To Install Windows Server 2012 On VirtualBox
- How To Bypass Torrent Connection Blocking By Your ISP
- How To Install Actual Facebook App On Kindle Fire
6/25/2014 9:42:17 PM

With a hierarchical table populated and indexed, you’re ready to start writing efficient queries against it using some more methods available on the hierarchyid type.

The IsDescendantOf Method

The IsDescendantOf method is invoked on one hierarchyid value and accepts another hierarchyid value as its parameter. It returns a bit (Boolean) value of 1 (true) if the hierarchyid that the method is invoked on is a descendant (either directly or indirectly) of the hierarchyid that is passed in as the parameter. Thus, this method essentially returns a subtree whose root is the node specified by the parameter. Because of its vertical traversal, it delivers very fast performance for tables that have a depth-first index.

You can easily query the employee table to return all the descendants (child rows, grandchild rows, and so on) of a particular employee using the IsDescendantOf method. For example, the following query lists all of Amy’s descendants.

DECLARE @AmyNodeId hierarchyid

SELECT @AmyNodeId = NodeId
FROM Employee
WHERE EmployeeId = 46

SELECT NodeId.ToString() AS NodeIdPath, *
FROM Employee
WHERE NodeId.IsDescendantOf(@AmyNodeId) = 1
ORDER BY NodeLevel, NodeId

This query selects all rows whose NodeId values are descendants of Amy (employee ID 46). Here is the result:

NodeIdPath NodeId NodeLevel EmployeeId EmployeeName Title
---------- ------ --------- ---------- ------------ ----------------------
/1/ 0x58 1 46 Amy Marketing Specialist
/1/1/ 0x5AC0 2 269 Cheryl Marketing Assistant
/1/2/ 0x5B40 2 389 Wanda Business Assistant
/1/1/1/ 0x5AD6 3 87 Richard Business Intern
/1/1/2/ 0x5ADA 3 90 Jeff Business Intern

(5 row(s) affected)

Notice that the result includes Amy in addition to all of her descendants. Amy is returned because she is considered to be her “own descendant” at the 0 level of the subtree. Thus, you have selected a subtree that includes all of Amy’s descendants, no matter how many levels deep they might exist beneath her, with Amy at the root.

To select only Amy’s immediate child rows that are just one level beneath her, you can use the GetAncestor method. (You used this method earlier to create the uspAddEmployee stored procedure.) For example:

SELECT NodeId.ToString() AS NodeIdPath, *
FROM Employee
WHERE NodeId.GetAncestor(1) =
(SELECT NodeId
FROM Employee
WHERE EmployeeId = 46)
ORDER BY NodeLevel, NodeId
GO

NodeIdPath NodeId NodeLevel EmployeeId EmployeeName Title
---------- ------ --------- ---------- ------------ ----------------------
/1/1/ 0x5AC0 2 269 Cheryl Marketing Assistant
/1/2/ 0x5B40 2 389 Wanda Business Assistant

(2 row(s) affected)

This time, the results list only Cheryl and Wanda, but not Amy nor any of Amy’s deeper descendants. That’s because you are requesting just the rows whose one-level-up ancestor is Amy (employee ID 46)—that is, just Amy’s immediate children.

If you wanted to retrieve all the employees exactly two levels down from a particular manager, you could pass the value 2 to the GetAncestor method. For example, to select the employees that report to the employees beneath Dave (that is, to see all the employees two levels beneath him), you could request rows whose grandparent is Dave (employee ID 6; that is, just Dave’s grandchildren), as shown here:

SELECT NodeId.ToString() AS NodeIdPath, *
FROM Employee
WHERE NodeId.GetAncestor(2) =
(SELECT NodeId
FROM Employee
WHERE EmployeeId = 6)
ORDER BY NodeLevel, NodeId
GO

NodeIdPath NodeId NodeLevel EmployeeId EmployeeName Title
---------- ------ --------- ---------- ------------ ----------------------
/1/1/ 0x5AC0 2 269 Cheryl Marketing Assistant
/1/2/ 0x5B40 2 389 Wanda Business Assistant
/2/1/ 0x6AC0 2 272 Mary Marketing Assistant
/3/1/ 0x7AC0 2 291 Keven Marketing Intern

(4 row(s) affected)

This query returned all employees that are two levels below Dave. The fact that some of them are cousins and not siblings (that is, some of them have different direct parents) is irrelevant. Being exactly two levels down beneath Dave qualifies them all for selection by this query. And because of its horizontal traversal, it delivers very fast performance with a breadth-first index defined on the table.

To find the root node in the hierarchy, simply invoke the GetRoot method on the hierarchyid data type itself using the double-colon syntax, as shown in the following code. This is the same method you used to create the first employee at the top of the tree.

SELECT NodeId.ToString() AS NodeIdPath, *
FROM Employee
WHERE NodeId = hierarchyid::GetRoot()
GO

NodeIdPath NodeId NodeLevel EmployeeId EmployeeName Title
---------- ------ --------- ---------- ------------ ----------------------
/ 0x 0 6 Dave Marketing Manager

(1 row(s) affected)
Other  
  •  Protecting SQL Server Data : Obfuscation Methods (part 4) - Truncation,Encoding, Aggregation
  •  Protecting SQL Server Data : Obfuscation Methods (part 3) - Numeric Variance,Nulling
  •  Protecting SQL Server Data : Obfuscation Methods (part 2) - Repeating Character Masking
  •  Protecting SQL Server Data : Obfuscation Methods (part 1) - Character Scrambling
  •  SQL Server 2012 : Managing Resources - Limiting Resource Use, Leveraging Data Compression
  •  SQL Server 2012 : Tuning Queries (part 3) - Using the Database Engine Tuning Advisor
  •  SQL Server 2012 : Tuning Queries (part 2) - Gathering Query Information with Extended Events
  •  SQL Server 2012 : Tuning Queries (part 1) - Understanding Execution Plans
  •  SQL Server :ONE-WAY ENCRYPTION - Creating the Interface (part 2) - Setting and Verifying Permissions to the Stored Procedures
  •  SQL Server :ONE-WAY ENCRYPTION - Creating the Interface (part 1) - Creating the View, Creating the Stored Procedures
  •  
    Top 10
    - Microsoft Visio 2013 : Adding Structure to Your Diagrams - Finding containers and lists in Visio (part 2) - Wireframes,Legends
    - Microsoft Visio 2013 : Adding Structure to Your Diagrams - Finding containers and lists in Visio (part 1) - Swimlanes
    - Microsoft Visio 2013 : Adding Structure to Your Diagrams - Formatting and sizing lists
    - Microsoft Visio 2013 : Adding Structure to Your Diagrams - Adding shapes to lists
    - Microsoft Visio 2013 : Adding Structure to Your Diagrams - Sizing containers
    - Microsoft Access 2010 : Control Properties and Why to Use Them (part 3) - The Other Properties of a Control
    - Microsoft Access 2010 : Control Properties and Why to Use Them (part 2) - The Data Properties of a Control
    - Microsoft Access 2010 : Control Properties and Why to Use Them (part 1) - The Format Properties of a Control
    - Microsoft Access 2010 : Form Properties and Why Should You Use Them - Working with the Properties Window
    - Microsoft Visio 2013 : Using the Organization Chart Wizard with new data
    REVIEW
    - First look: Apple Watch

    - 3 Tips for Maintaining Your Cell Phone Battery (part 1)

    - 3 Tips for Maintaining Your Cell Phone Battery (part 2)
    programming4us programming4us
    programming4us
     
     
    programming4us