我有一个视图,可以获得项目冲刺的平面视图。对于冲刺持续时间,这是一天一天的细分,未来和过去。
这是一个相当大的加入视图。我正在尝试使用该视图来获取运行速度非常慢的屏幕的一些细节。这很慢,因为对于sprint中的每个人来说,它都是调用视图(使用EF和Linq),过滤,然后做一些总和......每人几次。
我正在尝试创建一个使用CTE获取视图数据的存储过程,然后在较小的连接中使用它。而且它更快,但我正在与一个专栏作斗争。
这是CTE及其用途:
DECLARE @SprintId INT
SET @SprintId = 1006
;WITH Detail_CTE (PersonId, AssignedHours, AssignedProductiveHours, DateValue, CanBurnDown, OnHoliday )
AS
(
SELECT PersonId, AssignedHours, AssignedProductiveHours, DateValue, CanBurnDown, OnHoliday FROM vwSprintDailyBreakdown
WHERE SprintId = @SprintId
AND OnHoliday = 0
),
Detail_CTE_rem (PersonId, AssignedHours, AssignedProductiveHours, DateValue, CanBurnDown, OnHoliday )
AS
(
SELECT PersonId, AssignedHours, AssignedProductiveHours, DateValue, CanBurnDown, OnHoliday FROM vwSprintDailyBreakdown
WHERE SprintId = @SprintId
AND OnHoliday = 0
AND DateValue >= GETUTCDATE()
)
SELECT
psp.Id,
p.Firstname + ' '+ p.Surname,
rt.Description,
psp.JoinSprintDate,
psp.LeaveSprintDate,
psp.AssignedProductiveHours,
psp.AssignedHours,
SUM(cteTotal.AssignedProductiveHours) AS ProdHrs
FROM project_sprint_person psp
INNER JOIN project_person pp
ON pp.Id = psp.ProjectPersonId
AND pp.deleted IS NULL
INNER JOIN person p
ON p.Id = pp.PersonId
AND p.Deleted IS NULL
LEFT JOIN resource_type rt
ON rt.Id = psp.ResourceTypeId
LEFT JOIN Detail_CTE cteTotal
ON cteTotal.PersonId = p.Id
AND cteTotal.CanBurnDown = 1
--LEFT JOIN Detail_CTE_rem cteRemain
--ON cteRemain.PersonId = p.Id
--AND cteRemain.CanBurnDown = 1
WHERE psp.ProjectSprintId = @SprintId
GROUP BY psp.Id,
p.Firstname,
p.Surname,
rt.Description,
psp.JoinSprintDate,
psp.LeaveSprintDate,
psp.AssignedProductiveHours,
psp.AssignedHours,
rt.Weight
ORDER BY rt.Weight
以这种形式,它正在发挥作用。总和列100%罚款。
但是,我需要包括“剩余的生产时间”。为此,我想使用相同的CTE数据,但只获得“DateValue”> =今天日期的行。
我试图创建第二个CTE来执行此操作,如您所见,但是一旦我加入CTE,我现有的总和列值就会变得不正确。
我认为我不需要第二次CTE ...而是可以在查询中加入相同的CTE,将其作为新事物进行评价。然而,再次,当我尝试时,现有CTE的总和值出错了。
如何使用一个CTE(Detail_CTE)并将其用于两种不同的场景。一,我得到一列的总和,然后再获得一列的总和,以及数据收缩。
答案 0 :(得分:2)
听起来你只想要一个条件SUM()
,它不需要额外的JOIN
到cte:
SELECT
psp.Id,
p.Firstname + ' '+ p.Surname,
rt.Description,
psp.JoinSprintDate,
psp.LeaveSprintDate,
psp.AssignedProductiveHours,
psp.AssignedHours,
SUM(cteTotal.AssignedProductiveHours) AS ProdHrs
SUM(CASE WHEN DateValue >= GetUTCDate() THEN cteTotal.AssignedProductiveHours
ELSE 0
END) AS RemainingProductiveHours