【发布时间】:2013-09-01 00:17:31
【问题描述】:
我有一个项目 sprint 的平面视图。这是 sprint 期间的每日细分,未来和过去。
这是一个相当大的连接视图。我正在尝试使用该视图来获取运行非常缓慢的屏幕的一些详细信息。这很慢,因为对于 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' >= Todays date 的行。
如您所见,我尝试创建第二个 CTE 来执行此操作,但是一旦我加入该 CTE,我现有的总和列值就会变得不正确。
我认为我不需要第二个 CTE... 而是可以在查询中加入同一个 CTE,将其别名为新的东西。但是,当我再次尝试时,现有 CTE 的总和值出错了。
如何使用一个 CTE (Detail_CTE) 并将其用于两种不同的场景。一个,我得到一列的总和,然后又得到一列的总和,带有数据限制。
【问题讨论】:
-
用不同的别名加入同一个 cte 似乎是正确的方法。但是,这个查询有很多事情要做。您可能想开始一个新的并慢慢建立它。换句话说,采取婴儿步骤。
标签: sql sql-server common-table-expression