2016-01-24 36 views
-2

我有三個表:兩個分級表和它們之間的一個聯結。兩棵樹和它們之間的聯合表

Teams 
id idParent 
1 null 
2 1 
3 null 
4 null 
5 4 

Projects 
id idParent 
1 null 
2 null 
3 2 
4 2 
5 null 

TeamProjects 
idTeam idProject 
2  2 
3  1 
5  5 

一個項目總是依賴於至少一個團隊,這是teamprojects的目的。

我想要達到的效果:對每個對象(包括團隊和項目),我想知道什麼是方興未艾,子對象(ID concatened)

idObject ascendantTeams descendantTeam ascendantProjects descendantProjects 
1         2        7, 10 
2   1              7 
3                 6 
4    
5   4              10 
6   3   
7   2              8, 9 
8   2         7 
9   2         7 
10   5   

我想用linq實現查詢,但是我需要CTE(用於遞歸部分)和(stuff-for-xml)用於連接部分......並且既不需要將linq轉換爲實體。 所以我試圖讓一個視圖來幫助,但我沒有設法爲它寫的SQL。

你會如何解決這個問題,要麼與linq實體或SQL?

+1

請做到這一點。我認爲遞歸查詢是主要的絆腳石。 *展示你自己的嘗試*並專注於獲得這種權利。 (這使得這只是一個SQL問題)。 –

+0

你最終結果中的「idObject」是什麼意思?它是來自團隊還是項目表的ID? – Sunil

+0

是的,idObject可以從這兩個表中獲得一個值 – Proviste

回答

1

你有什麼不是很清楚。

因此,爲了提出解決方案,我做了一些假設。我假定一個項目將被包含在後裔項目中,以球隊爲基礎的結果(見dbo.GetProjectsForTeam),並且一個球隊將被包括在後裔球隊中以獲得基於項目的結果(參見dbo.GetTeamsForProject)。你的問題一點也不清楚。

您將需要創建標量值函數來實現您的方案。

標量值函數的調用方式

這些函數需要兩個參數 - 這將是後人a直系親屬或d類型參數,那將是team-團隊ID與id基於項目的查詢

團隊相關標量值的功能

CREATE FUNCTION [dbo].[GetTeamsForTeam](
       @teamType VARCHAR(20) , --either 'a' for ascendants or 'd' for descendants 
       @teamId INT) 
RETURNS VARCHAR(MAX) 
AS 
    BEGIN 
     DECLARE @list VARCHAR(MAX); 
     IF @teamType = 'a' 
      BEGIN 
       --get all parent teams 
       SELECT @list = COALESCE(@list+','+CAST(t.Id AS VARCHAR(10)) , CAST(t.Id AS VARCHAR(10))) 
       FROM dbo.Teams AS t 
       WHERE t.Id IN (SELECT t2.IdParent 
           FROM dbo.Teams AS t2 
           WHERE t2.id = @teamId 
           ); 
      END; 
     ELSE 
      BEGIN 
       --get all children teams including @teamId 
       SELECT @list = COALESCE(@list+','+CAST(t.Id AS VARCHAR(10)) , CAST(t.Id AS VARCHAR(10))) 
       FROM dbo.Teams AS t 
       WHERE t.Id IN (SELECT t2.Id 
           FROM dbo.Teams AS t2 
           WHERE t2.IdParent = @teamId 
             OR 
             t2.Id = @teamId 
           ); 
      END; 
     RETURN @list; 
    END; 
GO 


CREATE FUNCTION [dbo].[GetProjectsForTeam](
       @projectType VARCHAR(1) , --either 'a' for ascendants or 'd' for descendants 
       @teamId  INT) 
RETURNS VARCHAR(MAX) 
AS 
    BEGIN 
     DECLARE @projects VARCHAR(MAX); 
     IF @projectType = 'a' 
      BEGIN 
       --get projects for all the parents of @teamId 
       SELECT @projects = COALESCE(@projects+','+CAST(tp.idProject AS VARCHAR(10)) , CAST(tp.idProject AS VARCHAR(10))) 
       FROM dbo.TeamProjects AS tp 
       WHERE tp.idTeam IN (SELECT t.IdParent 
             FROM dbo.Teams AS t 
             WHERE t.Id = @teamId 
            ); 
      END; 
     ELSE 
      BEGIN 
       --get projects for all children of @teamId including @teamId 
       SELECT @projects = COALESCE(@projects+','+CAST(tp.idProject AS VARCHAR(10)) , CAST(tp.idProject AS VARCHAR(10))) 
       FROM dbo.TeamProjects AS tp 
       WHERE tp.idTeam IN (SELECT t.Id 
             FROM dbo.Teams AS t 
             WHERE t.IdParent = @teamId OR t.Id = @teamId 
            ); 
      END; 
     RETURN @projects; 
    END; 
GO 

使用上面標量值函數,基於團隊的查詢來實現自己的最終結果集如下所示。

SELECT t.id AS TeamId, 
     dbo.GetTeamsForTeam('a', t.id) AS ascendantTeams, 
     dbo.GetTeamsForTeam('d', t.id) AS descendantTeams, 
     dbo.GetProjectsForTeam('a', t.id) AS ascendantProjects, 
     dbo.GetProjectsForTeam('d', t.id) AS descendantProjects 
FROM Teams t; 

項目相關的標量值的功能

CREATE FUNCTION [dbo].[GetTeamsForProject] (
       @teamType VARCHAR(20) , --either 'a' for ascendants or 'd' for descendants 
       @projectId INT 
              ) 
RETURNS VARCHAR(MAX) 
AS 
    BEGIN 
     DECLARE @list VARCHAR(MAX); 
     IF @teamType = 'a' 
      BEGIN 
       --get all parent teams 
       SELECT @list = COALESCE(@list+','+CAST(t.Id AS VARCHAR(10)) , CAST(t.Id AS VARCHAR(10))) 
       FROM dbo.Teams AS t 
       WHERE t.Id IN (SELECT t2.IdParent 
           FROM dbo.Projects AS p INNER JOIN dbo.TeamProjects AS tp ON p.Id = tp.idProject 
                 INNER JOIN dbo.Teams AS t2 ON t2.id = tp.idTeam 
           WHERE p.id = @projectId 
           ); 
      END; 
     ELSE 
      BEGIN 
       --get all children teams including team for @projectId 
       SELECT @list = COALESCE(@list+','+CAST(t.Id AS VARCHAR(10)) , CAST(t.Id AS VARCHAR(10))) 
       FROM dbo.Teams AS t 
       WHERE t.Id IN (SELECT t2.Id 
           FROM dbo.Projects AS p INNER JOIN dbo.TeamProjects AS tp ON p.Id = tp.idProject 
                 INNER JOIN dbo.Teams AS t2 ON t2.id = tp.idTeam 
           WHERE p.IdParent = @projectId OR p.Id = @projectId 
           ); 
      END; 
     RETURN @list; 
    END; 

GO 


CREATE FUNCTION [dbo].[GetProjectsForProject] (
       @projectType VARCHAR(1) , --either 'a' for ascendants or 'd' for descendants 
       @projectId INT 
              ) 
RETURNS VARCHAR(MAX) 
AS 
    BEGIN 
     DECLARE @projects VARCHAR(MAX); 
     IF @projectType = 'a' 
      BEGIN 
       --get projects for all the parents of @projectId 
       SELECT @projects = COALESCE(@projects+','+CAST(p.idParent AS VARCHAR(10)) , CAST(p.idParent AS VARCHAR(10))) 
       FROM dbo.Projects AS p 
       WHERE p.Id IN (SELECT p.IdParent 
           FROM dbo.Projects AS p 
           WHERE p.Id = @projectId 
           ); 
      END; 
     ELSE 
      BEGIN 
       --get projects for all children of @projectd 
       SELECT @projects = COALESCE(@projects+','+CAST(p.id AS VARCHAR(10)) , CAST(p.id AS VARCHAR(10))) 
       FROM dbo.Projects AS p 
       WHERE p.IdParent IN (SELECT p.Id 
             FROM dbo.Projects AS p 
             WHERE p.IdParent = @projectId OR p.Id = @projectId  
            ); 
      END; 
     RETURN @projects; 
    END; 

GO 

利用上述基於項目的功能,基於項目的查詢的查詢是如下。

SELECT p.id AS ProjectId, 
     dbo.GetTeamsForProject('a', p.id) AS ascendantTeams, 
     dbo.GetTeamsForProject('d', p.id) AS descendantTeams, 
     dbo.GetProjectsForProject('a', p.id) AS ascendantProjects, 
     dbo.GetProjectsForProject('a', p.id) AS descendantProjects 
FROM dbo.Projects p; 

我使用的樣本數據和最終查詢的屏幕截圖如下。

Screen shot of Sample Data with Results

+0

非常感謝。這是晚了,我會檢查它並驗證它是否在早上確定 – Proviste

+0

當然。不用謝。 – Sunil