我正在处理查询:
USE SCRUMAPI2
DECLARE @userParam VARCHAR(100)
,@orgTeamPK VARCHAR(100)
,@statusParam VARCHAR(100)
,@search VARCHAR(100)
,@monthAgo VARCHAR(100)
SET @userParam = 'Amit Abc (abca)'
SET @orgTeamPK = '%'
SET @statusParam = '%'
SET @search = '%'
SET @monthAgo = '12/08/2013'
SELECT ROW_NUMBER() OVER (
ORDER BY TSK.[Status] DESC
) AS 'RowNumber'
,PDT.[Name] AS Project
,(
CASE
WHEN (
STY.KanBanProductId IS NOT NULL
AND STY.SprintId IS NULL
)
THEN 'KanBan'
WHEN (
STY.KanBanProductId IS NULL
AND STY.SprintId IS NOT NULL
)
THEN 'Sprint'
END
) AS ProjectType
,STY.[Number] StoryNumber
,STY.Title AS StoryTitle
,CONVERT(VARCHAR(20), STY.Effort) AS StoryPoints
,(
SELECT SUM(OriginalEstimateHours)
FROM Task TSK
LEFT JOIN Story STU ON TSK.StoryId = STU.PK_Story
LEFT JOIN Sprint SPT ON STU.SprintId = SPT.PK_Sprint
LEFT JOIN Product PDT ON STU.ProductId = PDT.PK_Product
LEFT JOIN [User] USR ON TSK.PointPerson = USR.DisplayName
WHERE TSK.PointPerson LIKE @userParam
AND (
(
@orgTeamPK = '%'
AND (
USR.[OrganizationalTeamId] LIKE @orgTeamPK
OR USR.[OrganizationalTeamId] IS NULL
)
)
OR (
@orgTeamPK <> '%'
AND (USR.[OrganizationalTeamId] LIKE @orgTeamPK)
)
)
AND STU.Number LIKE STY.Number
) AS StoryHoursEstimate
,ISNULL(SUM(DTH.[Hours]), 0) AS WorkHours
,'' AS Variance
,MAX(CASE
WHEN DTH.Hours != 0
THEN DTH.ActivityDate
END) AS LatestActivityDate
,(
CASE
WHEN (TSK.[Status] = 'Not Started')
THEN 'Active'
WHEN (TSK.[Status] = 'In Progress')
THEN 'Active'
WHEN (TSK.[Status] = 'Impeded')
THEN 'Active'
WHEN (TSK.[Status] = 'Done')
THEN 'Done'
END
) AS [Status]
FROM Task TSK
LEFT JOIN DailyTaskHours DTH ON TSK.PK_Task = DTH.TaskId
LEFT JOIN Story STY ON TSK.StoryId = STY.PK_Story
LEFT JOIN Sprint SPT ON STY.SprintId = SPT.PK_Sprint
LEFT JOIN Product PDT ON STY.ProductId = PDT.PK_Product
LEFT JOIN [User] USR ON TSK.PointPerson = USR.DisplayName
WHERE TSK.PointPerson LIKE @userParam
AND TSK.CreateDate >= CASE
WHEN TSK.[Status] = 'Done'
THEN @monthAgo
ELSE '1900-01-01'
END
AND TSK.[Status] LIKE @statusParam
AND PDT.[Name] != 'Overhead Codes'
AND (
(
@orgTeamPK = '%'
AND (
USR.[OrganizationalTeamId] LIKE @orgTeamPK
OR USR.[OrganizationalTeamId] IS NULL
)
)
OR (
@orgTeamPK <> '%'
AND (USR.[OrganizationalTeamId] LIKE @orgTeamPK)
)
)
AND TSK.Deleted IS NULL
AND (
(
STY.Number LIKE @search
OR STY.Number IS NULL
)
OR (
STY.Title LIKE @search
OR STY.Title IS NULL
)
OR (
TSK.NAME LIKE @search
OR TSK.NAME IS NULL
)
)
GROUP BY LEN(STY.[Number])
,STY.[Number]
,TSK.[Status]
,STY.Title
,PDT.[Name]
,TSK.PointPerson
,TSK.CreateDate
,TSK.[Name]
,STY.KanBanProductId
,STY.SprintId
,TSK.OriginalEstimateHours
,STY.Effort
ORDER BY CASE TSK.[Status]
WHEN 'Active'
THEN 1
WHEN 'Done'
THEN 2
END
以下是一些结果:
如图所示,有许多故事#PRO06-649。我希望将这些组合在一行上,在这一行上,每列当前的WorkHours将为该列求和。
我相信正在发生的事情之一就是我将WorkHours的总和高于我应该的水平。 我该如何做到这一点?
答案 0 :(得分:2)
我不会解决您的整个查询,因为它是way more than necessary to demonstrate the problem,但我将提供一些有关如何删除重复项的一些信息。鉴于此数据:
CREATE TABLE dbo.mytable
(
Project VARCHAR(255),
ProjectType VARCHAR(32),
StoryNumber CHAR(9),
WorkHours DECIMAL(10,2),
LastActivityDate DATETIME,
[Status] VARCHAR(10)
);
INSERT dbo.mytable VALUES
('Procurement Project','Sprint','PRO06-262',0.00, NULL,'Active'),
('Procurement Project','Sprint','PRO06-649',5.00, '20140107','Active'),
('Other Systems', 'KanBan','MISCX-232',3.00, '20131230','Active'),
('Procurement Project','Sprint','PRO06-249',10.00,'20131219','Active'),
('Procurement Project','Sprint','PRO06-249',15.00,'20140103','Active'),
('Procurement Project','Sprint','PRO06-651',8.00, '20131213','Active');
GO
在猜测实际需要的结果时,这些是两种基本方法:
使用汇总和GROUP BY
。
SELECT Project, ProjectType, StoryNumber, wh = SUM(WorkHours),
la = MAX(LastActivityDate), st = MIN([Status])
FROM dbo.MyTable
GROUP BY Project, ProjectType, StoryNumber;
这种方法不是很灵活,因为你经常想要比较最新活动日期的状态,例如,没有好的方法来表达纯粹的聚合,而不会引入复杂的自连接和多次扫描。
使用CTE和窗口函数。
;WITH x AS
(
SELECT Project, ProjectType, StoryNumber,
wh = SUM(WorkHours) OVER (PARTITION BY StoryNumber),
rn = ROW_NUMBER() OVER (PARTITION BY StoryNumber ORDER BY LastActivityDate DESC),
la = LastActivityDate,
st = [Status]
FROM dbo.MyTable
)
SELECT Project, ProjectType, StoryNumber, wh, la, st FROM x WHERE rn = 1;
这种方法显然更灵活,但更冗长,更不直观。
您选择哪种方法取决于您的要求以及哪些方法产生的结果与您之后的结果相符(或者可以进行调整)。
答案 1 :(得分:0)
你真的需要行号吗?
此外,除非你准备在所有具有不同值的字段上使用聚合函数 - 比如工作时间,故事点等,否则我觉得有办法通过分组将多行缩小为一个。