2009-12-15 4 views
1

У меня есть требование. Я дал следующей таблицеПомощь, необходимая для получения общего количества ресурсов (SQL Server 2005)

DownLineid UplineId Name DirectResources 
1    2  Sarvesh  7 
2   NULL  Admin   5 
3    2  Lonesh   10 
4    2  Swapna   2 
5    2  Priyanka  12 
8    2   Sumi   1 
6    5   Deepak   10 
7    5  Agnijita   6 
9    5   Me    1 

Сценария UplineId означает, что топ-менеджеры и означают линии менеджеров, работающими под Upliners.

Моя задача - выяснить общие ресурсы для Upliners. Требуемый выход:

UplineId DownLineid Name DirectResources TotalResources 
NULL   2   Admin   5    54 
2 3      Lonesh  10   null 
2 5      Priyanka 12    17 
5 7       Agnijita 6   null 
5 6       Deepak 10   null 
5 9       Me   1   null 
2 1     Sarvesh   7   null 
2 8     Sumi    1   null 
2 4     Swapna   2   null 

На самом деле, администратор является вершиной и имеет все ресурсы. поэтому общее количество всех ресурсов составляет 54.

Агниджита, Дипак и я находятся под Приянкой, и отныне счет равен 17 (6 + 10 + 1).

Для всех остальных нет downliners, отныне это не имеет значения.

Моя попытка до сих пор

declare @t table(DownLineid int,UplineId int,Name varchar(10),DirectResources int) 
insert into @t 
    select 1,2,'Sarvesh',7 union all select 2,Null,'Admin',5 union all 
    select 3,2,'Lonesh',10 union all select 4,2,'Swapna',2 union all 
    select 5,2,'Priyanka',12 union all select 8,2,'Sumi',1 union all 
    select 6,5,'Deepak',10 union all select 7,5,'Agnijita',6 union all 
    select 9,5,'Me',1 
select * from @t 
;with cte AS 
(

    SELECT 
     CAST(e.Name AS VARCHAR(1000)) AS [Path] 
     ,e.UplineId 
     ,e.DownLineid 
     ,e.Name 
     ,0 AS [Level] 
     ,e.DirectResources FROM @t e WHERE e.UplineId IS NULL 
    UNION ALL 

    SELECT CAST(c.[Path] + '/' + e.Name AS VARCHAR(1000)) AS [Path] 
     ,e.UplineId 
     ,e.DownLineid 
     ,e.Name 
     , c.[Level]+1 AS [Level] 
     ,e.DirectResources 

    FROM @t e 

    JOIN cte c ON e.UplineId = c.DownLineid 

) 
select 
UplineId 
,DownLineid 
, REPLICATE(' ', [Level]) + Name as [Name] 
,DirectResources 

FROM cte 
ORDER BY [Path] 

Я изо всех сил, чтобы найти общие ресурсы. Я использую SQL Server 2005.

Пожалуйста, помогите мне.

Заранее спасибо.

+0

В вашем примере, 'сумма admin' включает свой ресурс, но' один Priyanka' в не. Это предназначено? – Quassnoi

+0

Если вы планируете переходить на SQL Server 2008, похоже, вы можете использовать идентификаторы иерархии (http://blogs.msdn.com/manisblog/archive/2007/08/17/sql-server-2008-hierarchyid.aspx) – ram

+0

A [self join] [1] с предложениями [group by] [2] и [sum] [3] выглядит как правильное решение. [1]: http: //databases.about.com/od/sql/a/selfjoins.htm [2]: http: //technet.microsoft.com/en-us/library/ms177673.aspx [3 ]: http: //doc.ddart.net/mssql/sql70/setu-sus_18.htm – Oded

ответ

2
WITH q AS 
     (
     SELECT downlineID AS parent, downlineID AS id 
     FROM mytable 
     UNION ALL 
     SELECT q.parent, m.downlineID AS id 
     FROM q 
     JOIN mytable m 
     ON  m.uplineID = q.id 
     ) 
SELECT q.parent, 
     CASE 
     WHEN EXISTS 
     (
     SELECT NULL 
     FROM mytable mi 
     WHERE mi.uplineID = q.parent 
     ) 
     THEN SUM(directResources) 
     ELSE NULL 
     END AS TotalResources 
FROM q 
LEFT JOIN 
     mytable m 
ON  m.downlineID = q.id 
GROUP BY 
     q.parent 
+0

Я считаю, что это неверно. SQL Server допускает только реверсию сверху вниз, а не снизу вверх. Я думаю, что это приведет к тому, что «невозможно выполнить агрегатную функцию в выражении, содержащем исключение агрегата или подзапроса». – Paul

+0

'@ Paul': право,' EXISTS' должно быть вне суммы. Это реверсия сверху вниз (хотя «SQL Server» позволяет рекурсию в обоих направлениях). – Quassnoi

+0

О да, вы правы - глупый. – Paul

0

я это написал некоторое время назад в моем blog

with Manager AS (

select EmpID,ManID from EmpMan where ManID=1/* assuming that your VP ID is 1, or it can be the top most person whom you want to query on*/ 

union all 

select E.EmpID,E.ManID from EmpMan E 

join Manager M on E.ManID=M.EmpID) 

select * from Manager 
Смежные вопросы