views:

384

answers:

3

Trying to write a recursive CTE query, keep getting the following error: level, invalid column name

This is the query, where am I going wrong?

WITH OwnerHierarchy AS (
   SELECT PairID, 
          ChildID, 
          ParentID, 
          0 AS level
     FROM BusinessHierarchy
   UNION ALL
   SELECT e.PairID, 
          e.ChildID, 
          e.ParentID, 
          level + 1 AS level
     FROM BusinessHierarchy AS e 
     JOIN BusinessHierarchy AS eh ON e.ParentID = eh.ParentID)
 SELECT PairID, 
        ChildID, 
        ParentID, 
        level
    FROM OwnerHierarchy AS OwnerHierarchy_1
 ORDER BY level, ChildID, ParentID

This is ms sql server 2005.

+2  A: 

You need OwnerHierarchy somewhere in the second half of the CTE to be recursive. Instead, you have BusinessHierarchy twice.

Peter
+1  A: 

Just guessing at the exact requirements, but something like this.

WITH OwnerHierarchy(PairID, ChildID, ParentID, level)
AS 
(
     SELECT PairID, ChildID, ParentID, 0 AS level
     FROM BusinessHierarchy
     WHERE ParentID IS NULL
     UNION ALL
     SELECT e.PairID, e.ChildID, e.ParentID, level + 1 AS level
     FROM BusinessHierarchy AS e 
     INNER JOIN OwnerHierarchy AS eh 
     ON e.ParentID = eh. ChildID
     )
 SELECT     PairID, ChildID, ParentID, level
 FROM         OwnerHierarchy AS OwnerHierarchy_1
 ORDER BY level, ChildID, ParentID
Paul Creasey
yes, and write level as eh.level just to be safe
Hogan
Can't use the 'With' clause, which is annoying...
flavour404
I tried this several different ways and I am either getting no results (there are several test cases in the database) or visual studio crashes!
flavour404
OK, scratch that, we have two different versions of MS SQL and the test environment doesn't support common tables of course! However, it is returning no datasets which is weird as I know there is definitely a couple of test cases that should be returned at least!
flavour404
+1  A: 

There's three issues with what you posted:

WITH OwnerHierarchy AS (
   SELECT a.pairid, 
          a.childid, 
          a.parentid, 
          0 AS level
     FROM BusinessHierarchy a
    WHERE a.parentid IS NULL -- Point #1, see below
   UNION ALL
   SELECT b.PairID, 
          b.ChildID, 
          b.ParentID, 
          oh.level + 1 AS level
     FROM BusinessHierarchy AS b
     JOIN OwnerHierarchy oh ON oh.childid = b.parentid) -- Points #2 & 3, see below
 SELECT x.PairID, 
        x.ChildID, 
        x.ParentID, 
        x.level
    FROM OwnerHierarchy x
 ORDER BY x.level, x.ChildID, x.ParentID

Points:

  1. The top half of the UNION is missing what determines what the root nodes/records/rows are. I've assumed, hopefully correctly...
  2. You were joining BusinessHierarchy to itself, when the reference should be the CTE name
  3. The relationship between the CTE and original table needs to be correct, and in the correct direction

Props for using table aliases, but they weren't consistently used, and they should be as brief as possible. You don't need to use the AS when defining them, just a matter of style on that part.

Conclusion


I'm thinking the table aliases will deal with the level column not being found issue, but not 100%.

OMG Ponies
I am missing something as I am not getting any results. If I run the first part of the query I get nothing unless I remove the: WHERE a.parentid IS NULLLine, but when I run the entire query with this line removed then my IDE crashes. Truthfully I'm not really understanding all of the CTE aspects but I guess it is getting better the more I look at it. Thanks
flavour404
OK, I found out what the error was, which was awesome. This helped enormously, so thanks.
flavour404