posts - 0, comments - 1573, trackbacks - 0

Microsoft SQL Server 2005 - CTE Example of a simple hierarchy

I have a simple table here which shows a list of devices and each device can have a parent device except for the top item which has a <NULL> value for the ParentID column.

Using SQL 2005 CTE (Common Table Expression) to render this full hierarchy we could use a simple query such as this:

What this CTE is doing is allowing us to run a hierarchical query.

We first off find the root of our tree, which in this case is referenced by a NULL value in the ParentID column.

SELECT ParentID, ID,0, [DeviceType], cast(DeviceType as nvarchar(1024))
FROM DeviceType
WHERE ParentID IS null

This technically returns the same details as row #1 in the above graphic.

What the UNION ALL does is executes a query with a join against the CTE virtual table.

So we technically are sort of doing this:

Create Virtual Table with the following fields:

  • ParentID
  • ID,
  • Level,
  • DevieType,
  • Sort

This line inserts one row into the virtual table, the ID in this case will be 1 because that was the ID in our DeviceType table of the record with the ParentID of Null.

SELECT ParentID, ID,0, [DeviceType], cast(DeviceType as nvarchar(1024))
FROM DeviceType
WHERE ParentID IS null

Now we run the following query on the virtual table until every row is processed in the virtual table.

Note: This select is really like an insert into the virtual table. each row returned in the select is appended to our virtual table.

SELECT dt.ParentID, dt.ID, level+1, dt.DeviceType, cast(Sort + '|'+dt.Devicetype as nvarchar(1024))
FROM DeviceType dt INNER JOIN hierarchy h ON dt.ParentID = h.ID

So the first time it is run we see that h.ID would be equal to 1 which was the ID of the record with ParentID of Null. If there was any records matching this select statement they are added to the virtual table and this continues until all of the virtual table rows have been processed.

At the end of it we have a Virtual table that we can then do what we want with such as join it to another table or just return the data, in our case we run this sql statement.

select ID, ParentID, DeviceType, LEVEL, Sort
from Hierarchy
order by sort

But what happens if I have an record and want to find the parent hierarchy for it?

The following query will allow us to return the parent hierarchy for the item Virtual Server Hosts which has an ID of 10.

Note: There are problems with the results of this query!

Can you see the problem with the results?

We have correctly returned the parents starting from the Virtual Server Hosts and walked up the tree until we get to the root node. But if you look at the Level field it is not actually containing the correct value as the Virtual Server Hosts fields should be at level 3 and not at level 0.

Why is this?

Well we can't determine at what level the Virtual Server Hosts is at when we start creating the virtual table so we just hard code it to 0. 

The problem also is that if you wanted to render this out to say a web browser using the following hierarchy we would have to navigate through our records backwards.

  • Object
    • Server
      • Virtual Servers
        • Virtual Server Hosts

How to fix this!

What we can do in this case is run a second CTE joined to the first CTE because each CTE is just like a virtual table. When the first CTE has completed processing we are basically left with a table with records in it like below.

Our second CTE now just references the records in the first CTE as if it was a standard table.

As you can see in the query in the above graphic our second CTE starts by looking for a record which has the ParentID being set to NULL.

This will return our real parent as the first record to be inserted into our second virtual table. 

Now we run the following query on the second virtual table until every row is processed in the virtual table. Like the first virtual table, the select appends records to our virtual table and these records get processed until all records have been processed.

SELECT h.ParentID, h.ID, hr.LEVEL+1, h.DeviceType, cast(hr.Sort + '|'+h.sort as nvarchar(1024))
FROM Hierarchy h INNER JOIN HierarchyReverse hr ON h.ParentID = hr.ID

We have changed the join in the second CTE to join from the ParentID --> ItemID, which is the opposite of the first CTE which joined the ItemID --> ParentID. This allows us to navigate down the tree instead of up the tree.

Confusing? hopefully not....

What we end up with is this:

Now you may be wondering what this Sort column is and why we have it at all?

The reason is that we need to have something that is sortable, using the DeviceType is not since it would corrupt our hierarchy by giving us A-Z, the same goes for level, 0-9

What we do is we create a field that contains the hierarchy so far and then add the DeviceType to the end of it. This makes a sortable field that will not corrupt our hierarchy but give us A-Z sorting within each level of the hierarchy.

Notice the problem with this?

Well I have made a decision that all of my hierarchies of DeviceType will not exceed 1024 characters by casting the values with the statement : NVARCHAR(1024)

Well we could use a NVARCHAR(MAX) and the problem is resolved, but this is dependant on your knowledge of the application.

Hopefully this has shown you and me how the CTE's work while they are running - well it looks like that to me and it makes me understand it a bit easier as they can be hard to picture sometimes.

 

Print | posted on Thursday, September 06, 2007 12:30 PM |

Feedback

Gravatar

# re: Microsoft SQL Server 2005 - CTE Example of a simple hierarchy

Thank you very much, this was a very useful example. The sort field seems off to me (seems it should be object|server|virtual servers...). Casting devtype in the second select statement seems to help (after union in hierarch).
1/8/2008 11:50 AM | Bob
Gravatar

# re: Microsoft SQL Server 2005 - CTE Example of a simple hierarchy

Hi I am trying to use recursive query in sql server 2000 but I getting error "Server: Msg 156, Level 15, State 1, Line 1
Incorrect syntax near the keyword 'WITH'."

The code is given below :
WITH ManageFolders(FolderID, FolderName, ParenetFolderID,FolderLevel)
AS (
SELECT F1.FolderID, F1.FolderName, F1.ParentFolderID, 0 AS FolderLevel
FROM Folders F1
WHERE F1.ParentFolderID = 0
UNION ALL
SELECT F2.FolderID, F2.FolderName, F2.ParentFolderID, FolderLevel + 1
FROM Folders F2
INNER JOIN ManageFolders M
ON F2.ParentFolderID = M.FolderID
)
SELECT FolderID, FolderName, ParenetFolderID,FolderLevel
FROM ManageFolders ;
1/18/2008 7:37 AM | Gurjeet Saini
Gravatar

# re: Microsoft SQL Server 2005 - CTE Example of a simple hierarchy

Thank you very much, this was a very useful example. But I wonder that did LINQ in .NET 3.5 support this type of query?
7/22/2008 12:04 AM | Le Anh Dung
Gravatar

# Incorrect syntax near the keyword 'WITH'

Regarding the "Incorrect syntax near the keyword 'WITH'" error message...

Make sure the instance is SQL 2005 (or greater)

try
SELECT @@Version
7/31/2008 2:26 AM | MarownIOM
Gravatar

# re: Microsoft SQL Server 2005 - CTE Example of a simple hierarchy

Excellent. I was looking for this kind of sample in net. Thank you very much.
8/13/2008 6:46 AM | Eswar
Gravatar

# re: Microsoft SQL Server 2005 - CTE Example of a simple hierarchy

great job...
9/14/2008 7:31 PM | Muhammad Abdullah
Gravatar

# re: Microsoft SQL Server 2005 - CTE Example of a simple hierarchy

I am trying to build a query inside a CTE ,but getting an error as below. Any help?
DECLARE @SQL nvarchar(max)

;WITH PagedData AS
(
SELECT @SQL = 'SELECT intECFClaimsId AS ID,*,ROW_NUMBER() OVER (ORDER BY intECFClaimsId) AS [RowNumber],count(1) OVER() AS Total FROM tblECFClaims'
EXEC (@SQL)

)
SELECT * FROM PagedData


Error:
Msg 102, Level 15, State 1, Procedure spCustomPagingTest, Line 15
Incorrect syntax near '='.
Msg 102, Level 15, State 1, Procedure spCustomPagingTest, Line 18
Incorrect syntax near ')'.

Vini
8/13/2009 10:37 PM | Vini
Gravatar

# re: Microsoft SQL Server 2005 - CTE Example of a simple hierarchy

Really a great example. thanks
10/8/2009 11:04 PM | Madhes
Gravatar

# re: Microsoft SQL Server 2005 - CTE Example of a simple hierarchy

Excellent example...

How can we use the Sort column here to bind to a gridview so as to navigate till the child. or will it be displayed just like a row value.
10/22/2009 1:41 AM | Vaishali
Gravatar

# re: Microsoft SQL Server 2005 - CTE Example of a simple hierarchy

this query is very good .if hierarchy level is more than 100 it is not working
11/20/2009 9:27 PM | srikanth
Gravatar

# re: Microsoft SQL Server 2005 - CTE Example of a simple hierarchy

Thx for a great article. Based on your examples, I dropped the Sort column and added product lists per category (from another table) with a nominated category start node. The reverse example is great for product breadcrumbs too! Your examples got me out of a sticky situation! Thx Again
12/21/2009 10:40 PM | mitch
Gravatar

# re: Microsoft SQL Server 2005 - CTE Example of a simple hierarchy

Thanks for the good examples.
With the last example:
How would you get just the top level parent from a given ID?
1/6/2010 11:04 AM | OutOfTouch
Gravatar

# re: Microsoft SQL Server 2005 - CTE Example of a simple hierarchy

One more good article on this theme:

http://sqlblog.com/blogs/adam_machanic/archive/2006/07/12/swinging-from-tree-to-tree-using-ctes-part-2-adjacency-to-nested-intervals.aspx?google.com
1/27/2010 3:54 AM | Vasil
Gravatar

# re: Microsoft SQL Server 2005 - CTE Example of a simple hierarchy

Thanks for the great article. Basing on your example, I was able to create a hierarchy query on my table very easily.
3/19/2010 9:01 AM | Gowreesh
Gravatar

# re: Microsoft SQL Server 2005 - CTE Example of a simple hierarchy

thanks! great article. I got the solution for many queries .....

thanks again.
4/17/2010 11:28 AM | Anand
Gravatar

# re: Microsoft SQL Server 2005 - CTE Example of a simple hierarchy

this is a brillant explaination for hierarchy.
4/22/2010 9:43 PM | Ray
Gravatar

# re: Microsoft SQL Server 2005 - CTE Example of a simple hierarchy

Great article. Nicely explained. Keep it up with your work.
5/11/2010 2:27 AM | Ponsenei
Gravatar

# re: Microsoft SQL Server 2005 - CTE Example of a simple hierarchy

Thanks for the article . Great Explanation. !!
7/8/2010 5:10 AM | Anoop
Gravatar

# re: Microsoft SQL Server 2005 - CTE Example of a simple hierarchy

CTEs(Common Table Expressions) are one of the beautiful and the most powerful feature of SQL Server and are boon to SQL Server developers. These not only simplifies most of the complex operations in T-SQL but also do a lot more than one can imagine. Follow the link to know the details…
http://www.sqllion.com/2010/08/common-table-expressions-cte/
8/17/2010 12:41 AM | SQL Lion
Gravatar

# re: Microsoft SQL Server 2005 - CTE Example of a simple hierarchy

Excellent article.... thanks so much
10/3/2010 1:05 PM | Anil
Gravatar

# Knowledgeable Article Thanks.

This is usefull and knowledgeable article.
10/4/2010 7:17 PM | Syed Shahzad Ali
Gravatar

# re: Microsoft SQL Server 2005 - CTE Example of a simple hierarchy

Thanks, I have bookmarked this page. It is explained beautifully so that even I could understand it. Thanks again
10/14/2010 6:06 AM | tSQLj
Gravatar

# re: Microsoft SQL Server 2005 - CTE Example of a simple hierarchy

Hey, Thanks a lot. This is really helpful. Now i am much more comfortable using CTE :)
12/2/2010 10:50 PM | Sandy
Gravatar

# re: Microsoft SQL Server 2005 - CTE Example of a simple hierarchy

we get something new about your blog
4/5/2012 8:53 PM | 2d to 3d Video Converter
Gravatar

# re: Microsoft SQL Server 2005 - CTE Example of a simple hierarchy

Very nice code ! I've write the same code on my side but quite complex.
4/6/2012 5:27 PM | TMD A816
Gravatar

# re: Microsoft SQL Server 2005 - CTE Example of a simple hierarchy

How can i show this Hierarchy in Dropdown using (-- for Differentiate the Device Type)
4/18/2012 6:32 PM | Vishal
Gravatar

# re: Microsoft SQL Server 2005 - CTE Example of a simple hierarchy

<font size="3">longchamp outlet singapore store</font> 1/n This design features perhaps the biggest perforations I’ve ever seen on a handbag, and I can’t help but wonder how that will cheap longchamp bags play into the bag’s longterm wear. Cutting that many holes of that size into a piece of leather significantly changes how the longchamp outlet singapore material distributes stress and weight, which will likely lead to a shorter lifespan for the bag. Of course, if you’re buying longchamp outlet online a look this bold, you probably don’t want to wear it forever; a single season might do just fine. And now that I think of it, cheap longchamp if you’re looking for a bag in which to carry your extremely tiny dog, these might be nice, breathable options. Check out more longchamp outlet singapore store pictures of the bags after the jump and then let us know what you think in the comments. As Real Housewives has started to decline longchamp singapore store a bit over the past year or two, it’s always seemed to me that the show would be more interesting with fewer episodes that contained longchamp clearance more actual plot. If I had to re-edit this season, last night’s episode would be one that I’d keep almost entirely intact, which is about longchamp sale as good of an endorsement as I can give at this point. Now, on to the recap. <a hreplongchampoutletsale.com/">longchamp outlet
<br />
<br />
<br />
5/19/2012 8:22 PM | roboformroboform

Post Comment

Title  
Name  
Email
Url
Comment   
Please add 2 and 6 and type the answer here:

Powered by:
Powered By Subtext Powered By ASP.NET