CTE了解

时间:2013-09-01 00:17:31

标签: sql sql-server common-table-expression

我有一个视图,可以获得项目冲刺的平面视图。对于冲刺持续时间,这是一天一天的细分,未来和过去。

这是一个相当大的加入视图。我正在尝试使用该视图来获取运行速度非常慢的屏幕的一些细节。这很慢,因为对于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)并将其用于两种不同的场景。一,我得到一列的总和,然后再获得一列的总和,以及数据收缩。

1 个答案:

答案 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