CTE for Count the Binary Tree nodes

i have the table structure like this :
Create table #table(advId int identity(1,1),name nvarchar(100),Mode nvarchar(5),ReferId int )
insert into #table(name,Mode,ReferId)values('King','L',0)
insert into #table(name,Mode,ReferId)values('Fisher','L',1)
insert into #table(name,Mode,ReferId)values('Manasa','R',1)
insert into #table(name,Mode,ReferId)values('Deekshit','L',2)
insert into #table(name,Mode,ReferId)values('Sujai','R',2)
insert into #table(name,Mode,ReferId)values('Fedric','L',3)
insert into #table(name,Mode,ReferId)values('Bruce','R',3)
insert into #table(name,Mode,ReferId)values('paul','L',4)
insert into #table(name,Mode,ReferId)values('walker','R',4)
insert into #table(name,Mode,ReferId)values('Diesel','L',5)
insert into #table(name,Mode,ReferId)values('Jas','R',5)
insert into #table(name,Mode,ReferId)values('Edward','L',6)
insert into #table(name,Mode,ReferId)values('Lara','R',6)
select *from #table
How do i write the CTE for count the Binary tree nodes on level basis. Here is the example,
now,what i want to do is if i'm going to calculate the Count of the downline nodes.which means i want to calculate for '1' so the resultset which i'm expecting
count level mode
1 1 L
1 1 R
2 2 L
2 2 R
4 3 L
2 3 R
How do i acheive this,i have tried this
with cte (advId,ReferId,mode,Level)
as
select advId,ReferId,mode,0 as Level from #table where advid=1
union all
select a.advId,a.ReferId,a.mode ,Level+1 from #table as a inner join cte as b on b.advId=a.referId
select *From cte order by Level
i hope its clear. Thank you

See Itzik Ben-Gan examples for the subject
REATE TABLE Employees
  empid   int         NOT NULL,
  mgrid   int         NULL,
  empname varchar(25) NOT NULL,
  salary  money       NOT NULL,
  CONSTRAINT PK_Employees PRIMARY KEY(empid),
  CONSTRAINT FK_Employees_mgrid_empid
    FOREIGN KEY(mgrid)
    REFERENCES Employees(empid)
CREATE INDEX idx_nci_mgrid ON Employees(mgrid)
SET NOCOUNT ON
INSERT INTO Employees VALUES(1 , NULL, 'Nancy'   , $10000.00)
INSERT INTO Employees VALUES(2 , 1   , 'Andrew'  , $5000.00)
INSERT INTO Employees VALUES(3 , 1   , 'Janet'   , $5000.00)
INSERT INTO Employees VALUES(4 , 1   , 'Margaret', $5000.00) 
INSERT INTO Employees VALUES(5 , 2   , 'Steven'  , $2500.00)
INSERT INTO Employees VALUES(6 , 2   , 'Michael' , $2500.00)
INSERT INTO Employees VALUES(7 , 3   , 'Robert'  , $2500.00)
INSERT INTO Employees VALUES(8 , 3   , 'Laura'   , $2500.00)
INSERT INTO Employees VALUES(9 , 3   , 'Ann'     , $2500.00)
INSERT INTO Employees VALUES(10, 4   , 'Ina'     , $2500.00)
INSERT INTO Employees VALUES(11, 7   , 'David'   , $2000.00)
INSERT INTO Employees VALUES(12, 7   , 'Ron'     , $2000.00)
INSERT INTO Employees VALUES(13, 7   , 'Dan'     , $2000.00)
INSERT INTO Employees VALUES(14, 11  , 'James'   , $1500.00)
The first request is probably the most common one:
 returning an employee (for example, Robert whose empid=7) 
and his/her subordinates in all levels. 
The following CTE provides a solution to this request:
WITH EmpCTE(empid, empname, mgrid, lvl)
AS
  -- Anchor Member (AM)
  SELECT empid, empname, mgrid, 0
  FROM Employees
  WHERE empid = 7
  UNION ALL
  -- Recursive Member (RM)
  SELECT E.empid, E.empname, E.mgrid, M.lvl+1
  FROM Employees AS E
    JOIN EmpCTE AS M
      ON E.mgrid = M.empid
SELECT * FROM EmpCTE
Using this level counter you can limit the number of iterations
 in the recursion. For example, the following CTE is used to return 
all employees who are two levels below Janet:
WITH EmpCTEJanet(empid, empname, mgrid, lvl)
AS
  SELECT empid, empname, mgrid, 0
  FROM Employees
  WHERE empid = 3
  UNION ALL
  SELECT E.empid, E.empname, E.mgrid, M.lvl+1
  FROM Employees as E
    JOIN EmpCTEJanet as M
      ON E.mgrid = M.empid
  WHERE lvl < 2
SELECT empid, empname
FROM EmpCTEJanet
WHERE lvl = 2
As mentioned earlier, CTEs can refer to
 local variables that are defined within the same batch.
 For example, to make the query more generic, you can use 
variables instead of constants for employee ID and level:
DECLARE @empid AS INT, @lvl AS INT
SET @empid = 3 -- Janet
SET @lvl   = 2 -- two levels
WITH EmpCTE(empid, empname, mgrid, lvl)
AS
  SELECT empid, empname, mgrid, 0
  FROM Employees
  WHERE empid = @empid
  UNION ALL
  SELECT E.empid, E.empname, E.mgrid, M.lvl+1
  FROM Employees as E
    JOIN EmpCTE as M
      ON E.mgrid = M.empid
  WHERE lvl < @lvl
SELECT empid, empname
FROM EmpCTE
WHERE lvl = @lvl
Results generated thus far might be returned (but are not guaranteed to be), 
and error 530 is generated. You might think of using the MAXRECURSION option 
to implement the request to return employees who are two levels below 
Janet using the MAXRECURSION hint instead of the filter in the recursive member
WITH EmpCTE(empid, empname, mgrid, lvl)
AS
  SELECT empid, empname, mgrid, 0
  FROM Employees
  WHERE empid = 1
  UNION ALL
  SELECT E.empid, E.empname, E.mgrid, M.lvl+1
  FROM Employees as E
    JOIN EmpCTE as M
      ON E.mgrid = M.empid
SELECT * FROM EmpCTE
OPTION (MAXRECURSION 2)
WITH EmpCTE(empid, empname, mgrid, lvl, sortcol)
AS
  SELECT empid, empname, mgrid, 0,
    CAST(empid AS VARBINARY(900))
  FROM Employees
  WHERE empid = 1
  UNION ALL
  SELECT E.empid, E.empname, E.mgrid, M.lvl+1,
    CAST(sortcol + CAST(E.empid AS BINARY(4)) AS VARBINARY(900))
  FROM Employees AS E
    JOIN EmpCTE AS M
      ON E.mgrid = M.empid
SELECT
  REPLICATE(' | ', lvl)
    + '(' + (CAST(empid AS VARCHAR(10))) + ') '
    + empname AS empname
FROM EmpCTE
ORDER BY sortcol
(1) Nancy
 | (2) Andrew
 |  | (5) Steven
 |  | (6) Michael
 | (3) Janet
 |  | (7) Robert
 |  |  | (11) David
 |  |  |  | (14) James
 |  |  | (12) Ron
 |  |  | (13) Dan
 |  | (8) Laura
 |  | (9) Ann
 | (4) Margaret
 |  | (10) Ina
Best Regards,Uri Dimant SQL Server MVP,
http://sqlblog.com/blogs/uri_dimant/
MS SQL optimization: MS SQL Development and Optimization
MS SQL Consulting:
Large scale of database and data cleansing
Remote DBA Services:
Improves MS SQL Database Performance
SQL Server Integration Services:
Business Intelligence

Similar Messages

Maybe you are looking for