【问题标题】:CTE understandingCTE 理解
【发布时间】: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


【解决方案1】:

听起来您只需要一个条件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 

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2013-05-27
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2023-01-20
    • 2013-12-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多