我正在使用TSQL和AdventureWorks 2014尝试为由SalesOrderID指定的每个唯一订单计算所有LineTotal的总和。我要加入SalesOrderHead.SalesOrderID,因为在SalesOrderHeader中,SalesOrderID是主键。当每个SalesOrderID仅返回一条记录时,此查询将永久运行,并返回SalesOrderID的重复项。希望有道理...
我想做的是计算SumPerOrderCTE中按SalesOrderID分组的SUM(LineTotal),然后将其加入SalesOrderHeader以选择一些其他表,并且仅从SumPerOrder中选择具有与SalesOrderHeader匹配的SalesOrderID的记录。
有什么建议吗?我似乎无法弄清楚为什么它没有按期做。.
以下是输出(请注意,SalesOrderID都相同,并且应的差异大部分应为0,但不同): buggy_output
关于输出外观的小样本: desired_output
CREATE OR ALTER PROC [dbo].[SalesOrderDataReviewCTE]
AS
WITH SumPerOrder (SalesOrderID, CalculatedSubTotalFromDetail)
AS
(
SELECT
SalesOrderID
,SUM(LineTotal)
FROM AdventureWorks2014.Sales.SalesOrderDetail
GROUP BY SalesOrderID
)
SELECT
soh.SalesOrderID
,soh.SalesOrderNumber
,soh.SubTotal AS OriginalSubTotal
,spo.CalculatedSubTotalFromDetail
,(soh.SubTotal - spo.CalculatedSubTotalFromDetail) AS Difference
FROM AdventureWorks2014.Sales.SalesOrderHeader soh
INNER JOIN SumPerOrder spo
ON soh.SalesOrderID = spo.SalesOrderID
答案 0 :(得分:1)
为什么要使用CTE?
CTE只是使用可重复代码创建临时表的一种便捷且一次查询的方式。执行此操作时,SumPerOrder
表将丢失SalesOrderDetail
的所有索引。因此,与SalesOrderHeader
的联接比与SalesOrderHeader
与SalesOrderDetail
的直接联接所花费的时间要长得多。
更简单的方法是:
SELECT
soh.SalesOrderID
,soh.SalesOrderNumber
,soh.SubTotal AS OriginalSubTotal
,spo.SUM(LineTotal) as CalculatedSubTotalFromDetail
,(soh.SubTotal - spo.SUM(LineTotal)) AS Difference
FROM AdventureWorks2014.Sales.SalesOrderHeader soh
INNER JOIN AdventureWorks2014.Sales.SalesOrderDetail spo
ON soh.SalesOrderID = spo.SalesOrderID
GROUP BY spo.SalesOrderID,soh.SalesOrderNumber,soh.SubTotal
答案 1 :(得分:0)