0

プロジェクト スプリントのフラット ビューを取得するビューがあります。これは、スプリント期間の将来と過去の日別の内訳です。

かなり大きな結合ビューです。そのビューを使用して、実行速度が非常に遅い画面の詳細を取得しようとしています。スプリントの各人に対して、(EF と Linq を使用して) ビューを呼び出し、フィルター処理を行ってから、いくつかの合計を実行していたため、遅くなりました... 1 人あたり数回。

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' >= 今日の日付の行のみを取得します。

ご覧のとおり、これを行うために 2 番目の CTE を作成しようとしましたが、その CTE に参加するとすぐに、既存の合計列の値が正しくなくなります。

2 番目の CTE は必要ないと思います...代わりに、クエリで同じ CTE に参加して、新しいものとしてエイリアスすることができます。ただし、もう一度試してみると、既存の CTE の合計値がうまくいきません。

1 つの CTE (Detail_CTE) を使用して、2 つの異なるシナリオに使用するにはどうすればよいですか。1 つは、列の合計を取得する場所です。次に、列の合計をデータ制限付きで取得します。

4

1 に答える 1

2

cte にSUM()余分なものを必要としないconditional が必要なだけのように思えます。JOIN

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 
于 2013-09-01T03:02:35.970 に答える