所有
我在下面有这个查询,这是一对多的关系。
关系就是这样,一个故事可以有多个任务(1> M)每个任务可以有多个时间条目(M-M)
我希望在任务部分中第一次出现3个字段,并为每个故事取消其余部分。所以例如;
Story 1234
Tasks 12, 13, 14,15
Time entry 120, 121, 134, 135 etc....
任务OptimisticEstimate,ProbableEstimate和Pessimistic Estimate中有3个字段,当时间条目表链接到查询时,它会在任务级别重复(应该如此)。
我希望为每个任务获得第一次出现的这些字段,并将任何其他事件保留为NULL,以便在我们总结时估计不会与从时间输入的小时数相加。
希望这很清楚。
WITH
WorkItem_CTE AS
(-- Child Level (Task)
SELECT wi1.AreaID
,a.Name AS AreaName
,wi1.ProjectID
,wi1.IterationID
-- Work Items
,DATEADD(HOUR, DATEDIFF(HOUR, GETUTCDATE(), GETDATE()),wi1.CreatedDateUtc) AS WorkItemCreatedDTS
,wi1.WorkItemID
,wi1.[Type] AS WorkItemType
,wi1.Name AS WorkItemName
,wi1.[Status] AS WorkItemStatus
,wi1.[Priority] AS WorkItemPriority
,wi1.Complexity
,wi1.Estimate
-- Tasks
,DATEADD(HOUR, DATEDIFF(HOUR, GETUTCDATE(), GETDATE()),wi2.CreatedDateUtc) AS TaskCreatedDTS
,wi2.WorkItemID AS TaskID
,wi2.Name AS TaskName
,wi2.[Status] AS TaskStatus
,wi2.AssignedTo AS TaskAssignedTo
,wi2.EstimateOptimistic
,Case When wi2.EstimateProbable IS NULL Then (wi2.EstimateOptimistic + wi2.EstimatePessimistic)/2 Else wi2.EstimateProbable End As EstimateProbable
,wi2.EstimatePessimistic
,wi2.WorkCompleted
,wi2.WorkRemaining
FROM dbo.WorkItem wi1 WITH (NOLOCK)
INNER JOIN dbo.WorkItem wi2 WITH (NOLOCK)
ON wi1.WorkItemID = wi2.ParentID
AND wi2.[Status] <> 'Deleted'
LEFT OUTER JOIN dbo.Area a WITH (NOLOCK)
ON wi1.AreaID = a.AreaID
--LEFT OUTER JOIN dbo.Project p WITH (NOLOCK)
-- ON wi1.ProjectID = p.ProjectID
WHERE wi1.[Status] <> 'Deleted'
UNION ALL
-- Parent level (Story, Bug, Feedback)
SELECT wi1.AreaID
,a.Name AS AreaName
,wi1.ProjectID
,wi1.IterationID
-- Work Items
,DATEADD(HOUR, DATEDIFF(HOUR, GETUTCDATE(), GETDATE()),wi1.CreatedDateUtc) AS WorkItemCreatedDTS
,wi1.WorkItemID
,wi1.[Type] AS WorkItemType
,wi1.Name AS WorkItemName
,wi1.[Status] AS WorkItemStatus
,wi1.[Priority] AS WorkItemPriority
,wi1.Complexity
,wi1.Estimate
-- Tasks
,DATEADD(HOUR, DATEDIFF(HOUR, GETUTCDATE(), GETDATE()),wi2.CreatedDateUtc) AS TaskCreatedDTS
,wi2.WorkItemID AS TaskID
,wi2.Name AS TaskName
,wi2.[Status] AS TaskStatus
,wi2.AssignedTo AS TaskAssignedTo
,wi2.EstimateOptimistic
,Case When wi2.EstimateProbable IS NULL Then (wi2.EstimateOptimistic + wi2.EstimatePessimistic)/2 Else wi2.EstimateProbable End As EstimateProbable
,wi2.EstimatePessimistic
,wi2.WorkCompleted
,wi2.WorkRemaining
FROM dbo.WorkItem wi1 WITH (NOLOCK)
LEFT OUTER JOIN dbo.WorkItem wi2 WITH (NOLOCK)
ON wi1.WorkItemID = wi2.ParentID
AND wi2.[Status] <> 'Deleted'
LEFT OUTER JOIN dbo.Area a WITH (NOLOCK)
ON wi1.AreaID = a.AreaID
WHERE wi1.[Type] <> 'Task'
AND wi1.[Status] <> 'Deleted'
AND wi2.ParentID IS NULL
),
--Time Entry for Tasks
TimeEntry_CTE As
(SELECT te.WorkItemID
,te.ProjectID
,te.Date
,te.Hours
,te.CreatedBy
,te.CreatedDateUtc
,te.LastModifiedBy
,te.LastModifiedDateUtc
,te.Note
FROM TimeEntry te
)
SELECT wi.AreaID
,wi.AreaName
,wi.ProjectID
,p.Name AS ProjectName
,wi.WorkItemCreatedDTS
,wi.WorkItemID
,wi.WorkItemType
,wi.WorkItemName
,wi.WorkItemStatus
,wi.WorkItemPriority
,wi.Complexity
,wi.Estimate AS StoryEstimate
,wi.TaskCreatedDTS
,wi.TaskID
,wi.TaskName
,wi.EstimateOptimistic
,wi.EstimateProbable
,wi.EstimatePessimistic
,wi.TaskStatus
,wi.TaskAssignedTo
,wi.WorkCompleted
,wi.WorkRemaining
,te.WorkItemID as TimeWorkItemID
,te.ProjectID
,te.Date
,te.Hours
,te.CreatedBy
,te.CreatedDateUtc
,te.LastModifiedBy
,te.LastModifiedDateUtc
,te.Note
FROM WorkItem_CTE wi WITH (NOLOCK)
LEFT OUTER JOIN dbo.Project p WITH (NOLOCK)
ON wi.ProjectID = p.ProjectID
inner Join TimeEntry_CTE te With (nolock)
ON wi.TaskID = te.WorkItemID
先谢谢你的帮助。
根据建议修改代码。更近但不太正确。
WITH
WorkItem_CTE AS
(-- Child Level (Task)
SELECT wi1.AreaID
,a.Name AS AreaName
,wi1.ProjectID
,wi1.IterationID
-- Work Items
,DATEADD(HOUR, DATEDIFF(HOUR, GETUTCDATE(), GETDATE()),wi1.CreatedDateUtc) AS WorkItemCreatedDTS
,wi1.WorkItemID
,wi1.[Type] AS WorkItemType
,wi1.Name AS WorkItemName
,wi1.[Status] AS WorkItemStatus
,wi1.[Priority] AS WorkItemPriority
,wi1.Complexity
,wi1.Estimate
-- Tasks
,DATEADD(HOUR, DATEDIFF(HOUR, GETUTCDATE(), GETDATE()),wi2.CreatedDateUtc) AS TaskCreatedDTS
,wi2.WorkItemID AS TaskID
,wi2.Name AS TaskName
,wi2.[Status] AS TaskStatus
,wi2.AssignedTo AS TaskAssignedTo
,wi2.EstimateOptimistic
,Case When wi2.EstimateProbable IS NULL Then (wi2.EstimateOptimistic + wi2.EstimatePessimistic)/2 Else wi2.EstimateProbable End As EstimateProbable
,wi2.EstimatePessimistic
,wi2.WorkCompleted
,wi2.WorkRemaining
FROM dbo.WorkItem wi1 WITH (NOLOCK)
INNER JOIN dbo.WorkItem wi2 WITH (NOLOCK)
ON wi1.WorkItemID = wi2.ParentID
AND wi2.[Status] <> 'Deleted'
LEFT OUTER JOIN dbo.Area a WITH (NOLOCK)
ON wi1.AreaID = a.AreaID
--LEFT OUTER JOIN dbo.Project p WITH (NOLOCK)
-- ON wi1.ProjectID = p.ProjectID
WHERE wi1.[Status] <> 'Deleted'
UNION ALL
-- Parent level (Story, Bug, Feedback)
SELECT wi1.AreaID
,a.Name AS AreaName
,wi1.ProjectID
,wi1.IterationID
-- Work Items
,DATEADD(HOUR, DATEDIFF(HOUR, GETUTCDATE(), GETDATE()),wi1.CreatedDateUtc) AS WorkItemCreatedDTS
,wi1.WorkItemID
,wi1.[Type] AS WorkItemType
,wi1.Name AS WorkItemName
,wi1.[Status] AS WorkItemStatus
,wi1.[Priority] AS WorkItemPriority
,wi1.Complexity
,wi1.Estimate
-- Tasks
,DATEADD(HOUR, DATEDIFF(HOUR, GETUTCDATE(), GETDATE()),wi2.CreatedDateUtc) AS TaskCreatedDTS
,wi2.WorkItemID AS TaskID
,wi2.Name AS TaskName
,wi2.[Status] AS TaskStatus
,wi2.AssignedTo AS TaskAssignedTo
,wi2.EstimateOptimistic
,Case When wi2.EstimateProbable IS NULL Then (wi2.EstimateOptimistic + wi2.EstimatePessimistic)/2 Else wi2.EstimateProbable End As EstimateProbable
,wi2.EstimatePessimistic
,wi2.WorkCompleted
,wi2.WorkRemaining
FROM dbo.WorkItem wi1 WITH (NOLOCK)
LEFT OUTER JOIN dbo.WorkItem wi2 WITH (NOLOCK)
ON wi1.WorkItemID = wi2.ParentID
AND wi2.[Status] <> 'Deleted'
LEFT OUTER JOIN dbo.Area a WITH (NOLOCK)
ON wi1.AreaID = a.AreaID
WHERE wi1.[Type] <> 'Task'
AND wi1.[Status] <> 'Deleted'
AND wi2.ParentID IS NULL
),
--Time Entry for Tasks
TimeEntry_CTE As
(SELECT te.WorkItemID
,te.ProjectID
,te.Date
,te.Hours
,te.CreatedBy
,te.CreatedDateUtc
,te.LastModifiedBy
,te.LastModifiedDateUtc
,te.Note
FROM TimeEntry te
),
wi_CTE As
(SELECT wi.AreaID
,wi.AreaName
,wi.ProjectID
,p.Name AS ProjectName
,wi.WorkItemCreatedDTS
,wi.WorkItemID
,wi.WorkItemType
,wi.WorkItemName
,wi.WorkItemStatus
,wi.WorkItemPriority
,wi.Complexity
,wi.Estimate AS StoryEstimate
,wi.TaskCreatedDTS
,wi.TaskID
,wi.TaskName
,wi.EstimateOptimistic
,wi.EstimateProbable
,wi.EstimatePessimistic
,wi.TaskStatus
,wi.TaskAssignedTo
,wi.WorkCompleted
,wi.WorkRemaining
,te.WorkItemID as TimeWorkItemID
,te.ProjectID TimeProjectID
,te.Date
,Sum(te.Hours) Hours
,te.CreatedBy
,te.CreatedDateUtc
,te.LastModifiedBy
,te.LastModifiedDateUtc
,te.Note
FROM WorkItem_CTE wi WITH (NOLOCK)
LEFT OUTER JOIN dbo.Project p WITH (NOLOCK)
ON wi.ProjectID = p.ProjectID
inner Join TimeEntry_CTE te With (nolock)
ON wi.TaskID = te.WorkItemID
--where wi.WorkItemID =94
Group By
wi.AreaID
,wi.AreaName
,wi.ProjectID
,p.Name
,wi.WorkItemCreatedDTS
,wi.WorkItemID
,wi.WorkItemType
,wi.WorkItemName
,wi.WorkItemStatus
,wi.WorkItemPriority
,wi.Complexity
,wi.Estimate
,wi.TaskCreatedDTS
,wi.TaskID
,wi.TaskName
,wi.EstimateOptimistic
,wi.EstimateProbable
,wi.EstimatePessimistic
,wi.TaskStatus
,wi.TaskAssignedTo
,wi.WorkCompleted
,wi.WorkRemaining
,te.WorkItemID
,te.ProjectID
,te.Date
,te.Hours
,te.CreatedBy
,te.CreatedDateUtc
,te.LastModifiedBy
,te.LastModifiedDateUtc
,te.Note),
cte AS (SELECT wi_cte.*, ROW_NUMBER() OVER(PARTITION BY WorkItemID, TaskID ORDER BY TimeWorkItemID) RN
FROM wi_CTE
)
SELECT
AreaID
,AreaName
,ProjectID
,ProjectName
,WorkItemCreatedDTS
,WorkItemID
,WorkItemType
,WorkItemName
,WorkItemStatus
,WorkItemPriority
,Complexity
,StoryEstimate
,TaskCreatedDTS
,TaskID
,TaskName
,EstimateOptimistic
,EstimateProbable
,EstimatePessimistic
,TaskStatus
,TaskAssignedTo
,WorkCompleted
,WorkRemaining
,WorkItemID
,ProjectID
,Date
,Hours
,CreatedBy
,CreatedDateUtc
,LastModifiedBy
,LastModifiedDateUtc
,Note
,RN
,SUM(CASE WHEN RN = 1 THEN Hours END) AS SumTime
FROM cte
Where RN=1
GROUP BY
AreaID
,AreaName
,ProjectID
,ProjectName
,WorkItemCreatedDTS
,WorkItemID
,WorkItemType
,WorkItemName
,WorkItemStatus
,WorkItemPriority
,Complexity
,StoryEstimate
,TaskCreatedDTS
,TaskID
,TaskName
,EstimateOptimistic
,EstimateProbable
,EstimatePessimistic
,TaskStatus
,TaskAssignedTo
,WorkCompleted
,WorkRemaining
,WorkItemID
,ProjectID
,Date
,Hours
,CreatedBy
,CreatedDateUtc
,LastModifiedBy
,LastModifiedDateUtc
,Note
,RN
我得到了什么
ProjectID ProjectName WorkItemID WorkItemType WorkItemName EstimateOptimistic EstimateProbable EstimatePessimistic RN SumTime
11 Data Group 94 Story Backlog Report with new logic 2 3 4 1 8
11 Data Group 94 Story Backlog Report with new logic 2 3 4 2 4
11 Data Group 94 Story Backlog Report with new logic 2 3 4 3 4
11 Data Group 94 Story Backlog Report with new logic 2 3 4 4 4
11 Data Group 94 Story Backlog Report with new logic 2 3 4 1 4
11 Data Group 94 Story Backlog Report with new logic 2 3 4 2 4
11 Data Group 94 Story Backlog Report with new logic 2 3 4 3 4
11 Data Group 94 Story Backlog Report with new logic 2 3 4 4 8
11 Data Group 94 Story Backlog Report with new logic 2 3 4 5 3
What I'm Looking for
ProjectID ProjectName WorkItemID WorkItemType WorkItemName EstimateOptimistic EstimateProbable EstimatePessimistic RN SumTime
11 Data Group 94 Story Backlog Report with new logic 2 3 4 1 8
11 Data Group 94 Story Backlog Report with new logic NULL NULL NULL 2 4
11 Data Group 94 Story Backlog Report with new logic NULL NULL NULL 3 4
11 Data Group 94 Story Backlog Report with new logic NULL NULL NULL 4 4
11 Data Group 94 Story Backlog Report with new logic 2 3 4 1 4
11 Data Group 94 Story Backlog Report with new logic NULL NULL NULL 2 4
11 Data Group 94 Story Backlog Report with new logic NULL NULL NULL 3 4
11 Data Group 94 Story Backlog Report with new logic NULL NULL NULL 4 8
11 Data Group 94 Story Backlog Report with new logic NULL NULL NULL 5 3
希望这有助于澄清我正在努力的目标。
答案 0 :(得分:0)
我建议使用条件SUM()
和ROW_NUMBER()
函数。
假设上面的查询输出如下数据:
Story, Task, TimeEntry
1234, 12, 120
1234, 12, 121
1234, 12, 134
1234, 13, 135
1234, 13, 120
1234, 13, 121
1234, 13, 134
1234, 14, 135
1234, 14, 120
1234, 14, 121
1234, 14, 134
1234, 14, 135
你可以用这个:
;WITH cte AS (SELECT *, ROW_NUMBER() OVER(PARTITION BY Story, Task ORDER BY TimeEntry) RN
FROM Table1
)
SELECT Story, Task, SUM(CASE WHEN RN = 1 THEN TimeEntry END) AS SumTime
FROM cte
GROUP BY Story, Task
演示:SQL Fiddle
对于Story
和Task
的每个组合,每行都会编号,从1开始,允许您使用RN = 1
的条件来避免聚合重复的行。既然您说重复这些值,那么您对ORDER BY
的{{1}}子句中的内容并不重要。