2010-04-06 84 views
2

一個項目具有多個任務,其具有多個分配SQL查詢 - 從層次結構的兩個不同水平

獲取和的

項目(1-N) - >任務(1-N) - >分配

甲任務表上的字段是計劃小時數。

Assignments表上的字段是Assigned Hours。

如何在單個查詢中獲得所有項目的計劃小時數和分配小時數?

回答

5
select p.ProjectID, t.PlannedHoursSum, a.AssignedHoursSum 
from Projects p 
inner join (
    select ProjectID, sum(PlannedHours) as PlannedHoursSum 
    from Tasks 
    group by ProjectID 
) t on p.ProjectID = t.ProjectID 
inner join (
    select t.ProjectID, sum(AssignedHours) as AssignedHoursSum 
    from Tasks t 
    inner join Assignments a on t.TaskID = a.TaskID 
    group by t.ProjectID 
) a on p.ProjectID = a.ProjectID 
+0

這非常接近我要去的地方。謝謝! – 2010-04-06 22:19:52

+0

@Matthew - 我真的不在乎代表,但如果我維護你的應用程序,我寧願在我的答案中看到更簡潔的版本。我還比較了這兩個答案的查詢計劃,估計這個問題需要我的答案的兩倍。很明顯,只有在您嘗試使用大型數據集時纔會知道,但需要考慮。 – ChaosPandion 2010-04-06 22:25:15

+0

@Matthew瓊斯,我同意@ChaosPandion在這一個。 'Sum Over Partition'比@OrbMan使用的子查詢和臨時表更方便。 – 2010-04-06 23:18:40

6

編輯:這個答案給出了不正確的結果,但我將它留作歷史用途。

我認爲這會幫助你。但我無法弄清楚如何擺脫Distinct

Select Distinct 
     Project.ProjectId, 
     Sum(Task.PlannedHours) 
      Over (Partition By Project.ProjectId) As PlannedHours, 
     Sum(Assignment.AssignedHours) 
      Over (Partition By Project.ProjectId) As AssignedHours 
From Project 
    Inner Join Task On Project.ProjectId = Task.ProjectId 
    Inner Join Assignment On Task.TaskId= Assignment.AssignmentId 

這是我的測試腳本。

Declare @Project Table (ProjectId Int) 
Declare @Task Table (TaskId Int, ProjectId Int, PlannedHours Int) 
Declare @Assignment Table (AssignmentId Int, TaskId Int, AssignedHours Int) 

Insert Into @Project (ProjectId) values (1) 
Insert Into @Project (ProjectId) values (2) 
Insert Into @Project (ProjectId) values (3) 

Insert Into @Task (TaskId, ProjectId, PlannedHours) values (1, 1, 10) 
Insert Into @Task (TaskId, ProjectId, PlannedHours) values (2, 1, 10) 
Insert Into @Task (TaskId, ProjectId, PlannedHours) values (3, 2, 11) 
Insert Into @Task (TaskId, ProjectId, PlannedHours) values (4, 3, 12) 

Insert Into @Assignment (AssignmentId, TaskId, AssignedHours) values (1, 1, 2) 
Insert Into @Assignment (AssignmentId, TaskId, AssignedHours) values (2, 1, 2) 
Insert Into @Assignment (AssignmentId, TaskId, AssignedHours) values (3, 2, 2) 
Insert Into @Assignment (AssignmentId, TaskId, AssignedHours) values (4, 3, 3) 

Select Distinct 
     Project.ProjectId, 
     Sum(Task.PlannedHours) 
      Over (Partition By Project.ProjectId) As PlannedHours, 
     Sum(Assignment.AssignedHours) 
      Over (Partition By Project.ProjectId) As AssignedHours 
From @Project Project 
    Inner Join @Task Task On Project.ProjectId = Task.ProjectId 
    Inner Join @Assignment Assignment On Task.TaskId= Assignment.AssignmentId 
+1

+1使用'求和Partition',而不是子查詢和臨時表。 – 2010-04-06 23:19:38