zac*_*zac 1 sql-server cte union
WITH [ProgressInvoicesPeriodCost] AS
(
SELECT
ProgressInvoices.ProjectId
, ProgressInvoices.PeriodId
, SUM(ProgressInvoiceDetails.TotalThisInvoice) AS TotalThisInvoice
FROM
CostManagement_ProgressInvoices AS ProgressInvoices
LEFT JOIN CostManagement_ProgressInvoiceDetails AS ProgressInvoiceDetails
ON ProgressInvoices.Id = ProgressInvoiceDetails.ProgressInvoiceId
WHERE
ProgressInvoices.ProjectId IN (@Projectlisting)
GROUP BY
ProgressInvoices.ProjectId
, ProgressInvoices.PeriodId
)
[CommitmentCOPeriodCost] AS
(
SELECT
CommitmentCOs.ProjectId
, CommitmentCODetails.PeriodId
, SUM(CommitmentCODetails.AmountApproved) AS AmountApproved
FROM
CostManagement_CommitmentCOs AS CommitmentCOs
LEFT JOIN CostManagement_CommitmentCODetails AS CommitmentCODetails
ON CommitmentCOs.Id = CommitmentCODetails.CommitmentCOId
WHERE
CommitmentCOs.ProjectId IN (@Projectlisting) AND CommitmentCOs.PostAsId = 2
GROUP BY
CommitmentCOs.ProjectId
, CommitmentCODetails.PeriodId
)
[CommitmentPeriodCost] AS
(
SELECT
Commitments.ProjectId
, CommitmentDetails.PeriodId
, SUM(CommitmentDetails.TotalCost) AS TotalCost
FROM
CostManagement_Commitments AS Commitments
LEFT JOIN CostManagement_CommitmentDetails AS CommitmentDetails
ON Commitments.Id = CommitmentDetails.CommitmentId
WHERE
Commitments.ProjectId IN (@Projectlisting)
GROUP BY
Commitments.ProjectId
, CommitmentDetails.PeriodId
)
SELECT
ProjectId
,ProjectName
,'INV' as GroupRecordType
,'INV' as RecordType
, PeriodId
, Periods.Period
, TotalThisInvoice AS TotalCost
, (
SELECT SUM(TotalThisInvoice)
FROM ProgressInvoicesPeriodCost AS RunningCost
WHERE ProjectId = ProgressInvoicesPeriodCost.ProjectId
AND PeriodId <= ProgressInvoicesPeriodCost.PeriodId
) AS RunningTotal
FROM
[ProgressInvoicesPeriodCost]
LEFT OUTER JOIN Periods
ON ProgressInvoicesPeriodCost.PeriodId = Periods.Id
LEFT OUTER JOIN Projects
ON ProgressInvoicesPeriodCost.ProjectId = Projects.Id
Where (Period <= @ToPeriod) and ProgressInvoicesPeriodCost.ProjectId IN (@Projectlisting)AND 'INV' IN (@RecordTypes)
ORDER BY
ProjectId
, Period
UNION
SELECT
ProjectId
,ProjectName
,'COM' as GroupRecordType
,'CO' as RecordType
, PeriodId
, Periods.Period
, AmountApproved AS TotalCost
, (
SELECT SUM(AmountApproved)
FROM CommitmentCOPeriodCost AS RunningCost
WHERE ProjectId = CommitmentCOPeriodCost.ProjectId
AND PeriodId <= CommitmentCOPeriodCost.PeriodId
) AS RunningTotal
FROM
[CommitmentCOPeriodCost]
LEFT OUTER JOIN Periods
ON CommitmentCOPeriodCost.PeriodId = Periods.Id
LEFT OUTER JOIN Projects
ON CommitmentCOPeriodCost.ProjectId = Projects.Id
Where (Period <= @ToPeriod) and CommitmentCOPeriodCost.ProjectId IN (@Projectlisting)AND 'CO' IN (@RecordTypes)
ORDER BY
ProjectId
, Period
UNION
SELECT
ProjectId
,ProjectName
,'COM' as GroupRecordType
,'COM' as RecordType
, PeriodId
, Periods.Period
, TotalCost
, (
SELECT SUM(TotalCost)
FROM CommitmentPeriodCost AS RunningCost
WHERE ProjectId = CommitmentPeriodCost.ProjectId
AND PeriodId <= CommitmentPeriodCost.PeriodId
) AS RunningTotal
FROM
[CommitmentPeriodCost]
LEFT OUTER JOIN Periods
ON CommitmentPeriodCost.PeriodId = Periods.Id
LEFT OUTER JOIN Projects
ON CommitmentPeriodCost.ProjectId = Projects.Id
Where (Period <= @ToPeriod) and CommitmentPeriodCost.ProjectId IN (@Projectlisting)AND 'COM' IN (@RecordTypes)
ORDER BY
ProjectId
, Period
Run Code Online (Sandbox Code Playgroud)
我需要帮助尝试将这 3 个与 AS 部分联合。我收到以下错误:
!
简单说一下嵌套 CTE,每次引用它们时都会对其进行评估。换句话说,它们的行为不像临时表,数据没有以某种特殊方式缓存。因此,对于像您一样多次引用的 CTE(即一次在 UNION 中,一次在 RunningTotal 子查询中),可能会降低性能。我用您的查询设置了一个简单的装备,只有几百行来演示这一点。第一个调用(43,070 次读取)是您的查询,接下来的四个一起是我使用临时表来缓存 CTE 结果的重写,总共只注册了 702 次读取:
IF OBJECT_ID('tempdb..#ProgressInvoicesPeriodCost') IS NOT NULL DROP TABLE tempdb..#ProgressInvoicesPeriodCost
IF OBJECT_ID('tempdb..#CommitmentCOPeriodCost') IS NOT NULL DROP TABLE tempdb..#CommitmentCOPeriodCost
IF OBJECT_ID('tempdb..#CommitmentPeriodCost') IS NOT NULL DROP TABLE tempdb..#CommitmentPeriodCost
;WITH [ProgressInvoicesPeriodCost] AS
(
SELECT
ProgressInvoices.ProjectId
, ProgressInvoices.PeriodId
, SUM(ProgressInvoiceDetails.TotalThisInvoice) AS TotalThisInvoice
FROM
CostManagement_ProgressInvoices AS ProgressInvoices
LEFT JOIN CostManagement_ProgressInvoiceDetails AS ProgressInvoiceDetails
ON ProgressInvoices.Id = ProgressInvoiceDetails.ProgressInvoiceId
WHERE
ProgressInvoices.ProjectId = @Projectlisting
GROUP BY
ProgressInvoices.ProjectId
, ProgressInvoices.PeriodId
)
SELECT *
INTO #ProgressInvoicesPeriodCost
FROM [ProgressInvoicesPeriodCost]
;WITH [CommitmentCOPeriodCost] AS
(
SELECT
CommitmentCOs.ProjectId
, CommitmentCODetails.PeriodId
, SUM(CommitmentCODetails.AmountApproved) AS AmountApproved
FROM
CostManagement_CommitmentCOs AS CommitmentCOs
LEFT JOIN CostManagement_CommitmentCODetails AS CommitmentCODetails
ON CommitmentCOs.Id = CommitmentCODetails.CommitmentCOId
WHERE
CommitmentCOs.ProjectId = @Projectlisting
AND CommitmentCOs.PostAsId = 2
GROUP BY
CommitmentCOs.ProjectId
, CommitmentCODetails.PeriodId
)
SELECT *
INTO #CommitmentCOPeriodCost
FROM [CommitmentCOPeriodCost]
;WITH [CommitmentPeriodCost] AS
(
SELECT
Commitments.ProjectId
, CommitmentDetails.PeriodId
, SUM(CommitmentDetails.TotalCost) AS TotalCost
FROM
CostManagement_Commitments AS Commitments
LEFT JOIN CostManagement_CommitmentDetails AS CommitmentDetails
ON Commitments.Id = CommitmentDetails.CommitmentId
WHERE
Commitments.ProjectId = @Projectlisting
GROUP BY
Commitments.ProjectId
, CommitmentDetails.PeriodId
)
SELECT *
INTO #CommitmentPeriodCost
FROM [CommitmentPeriodCost]
SELECT
ProjectId
,ProjectName
,'INV' as GroupRecordType
,'INV' as RecordType
, PeriodId
, Periods.Period
, TotalThisInvoice AS TotalCost
, (
SELECT SUM(TotalThisInvoice)
FROM #ProgressInvoicesPeriodCost AS RunningCost
WHERE ProjectId = ProgressInvoicesPeriodCost.ProjectId
AND PeriodId <= ProgressInvoicesPeriodCost.PeriodId
) AS RunningTotal
FROM
#ProgressInvoicesPeriodCost ProgressInvoicesPeriodCost
LEFT OUTER JOIN Periods
ON ProgressInvoicesPeriodCost.PeriodId = Periods.Id
LEFT OUTER JOIN Projects
ON ProgressInvoicesPeriodCost.ProjectId = Projects.Id
WHERE (Period <= @ToPeriod)
AND ProgressInvoicesPeriodCost.ProjectId = @Projectlisting
AND 'INV' = @RecordTypes
UNION ALL
SELECT
ProjectId
,ProjectName
,'COM' as GroupRecordType
,'CO' as RecordType
, PeriodId
, Periods.Period
, AmountApproved AS TotalCost
, (
SELECT SUM(AmountApproved)
FROM #CommitmentCOPeriodCost AS RunningCost
WHERE ProjectId = CommitmentCOPeriodCost.ProjectId
AND PeriodId <= CommitmentCOPeriodCost.PeriodId
) AS RunningTotal
FROM
#CommitmentCOPeriodCost CommitmentCOPeriodCost
LEFT OUTER JOIN Periods
ON CommitmentCOPeriodCost.PeriodId = Periods.Id
LEFT OUTER JOIN Projects
ON CommitmentCOPeriodCost.ProjectId = Projects.Id
WHERE (Period <= @ToPeriod) and CommitmentCOPeriodCost.ProjectId = @Projectlisting
AND 'CO' = @RecordTypes
UNION ALL
SELECT
ProjectId
,ProjectName
,'COM' as GroupRecordType
,'COM' as RecordType
, PeriodId
, Periods.Period
, TotalCost
, (
SELECT SUM(TotalCost)
FROM #CommitmentPeriodCost AS RunningCost
WHERE ProjectId = CommitmentPeriodCost.ProjectId
AND PeriodId <= CommitmentPeriodCost.PeriodId
) AS RunningTotal
FROM
#CommitmentPeriodCost CommitmentPeriodCost
LEFT OUTER JOIN Periods
ON CommitmentPeriodCost.PeriodId = Periods.Id
LEFT OUTER JOIN Projects
ON CommitmentPeriodCost.ProjectId = Projects.Id
Where (Period <= @ToPeriod) and CommitmentPeriodCost.ProjectId = @Projectlisting
AND 'COM' = @RecordTypes
ORDER BY
ProjectId
, Period
Run Code Online (Sandbox Code Playgroud)
结果:

尝试用您的数据重写,比较读取,如果您发现差异,请告诉我们。
关于“In”的另一个词 - 它的行为方式与您认为的方式不同。因此,我已将查询中的所有“In”引用转换为“=”。如果这对您不起作用,请为您的变量@Projectlisting、@ToPeriod 和@RecordTypes 发布示例值。同时,您可能希望查看 Erland Sommarskog 关于此主题的出色文章
http://www.sommarskog.se/arrays-in-sql.html