SQLZoo难题#12 AdventureWorks评估

时间:2013-12-13 01:09:18

标签: sql select join group-by

我是数据库世界的新手,我刚开始学习并发现SQLZoo网站非常有帮助。 我在AdventureWorks数据库中遇到了这个问题。

http://sqlzoo.net/wiki/AdventureWorks_hard_questions

12.对于每个订单显示SalesOrderID和SubTotal计算三种方式:   A)来自SalesOrderHeader   B)OrderQty * UnitPrice的总和   C)OrderQty * ListPrice的总和

出于某种原因,我无法想出这个。非常感谢任何帮助。

这是我的疑问:

SELECT 
   A.SalesOrderID,
   A.SubTotal AS SubTotalA,
   B.SubtotalB,
   C.SubtotalC 
FROM SalesOrderHeader A
JOIN
(
   SELECT SUM(sodB.OrderQty*sodB.UnitPrice) AS SubTotalB 
   FROM SalesOrderDetail sodB 
   JOIN ProductAW pawB 
   ON pawB.ProductID=sodB.ProductID
   GROUP BY sodB.SalesOrderID
)  AS B
JOIN
(
   SELECT SUM(sodC.OrderQty*pawC.ListPrice) AS SubTotalC 
   FROM SalesOrderDetail sodC 
   JOIN ProductAW pawC 
   ON pawC.ProductID=sodC.ProductID
   GROUP BY sodC.SalesOrderID
 )  AS C

出于某种原因,当我在JOIN之外单独运行SELECT语句B或C时,我得到了我期望的结果,但是当我放置在JOIN中时,SubTotalB或Subtotal C的所有值都重复显示与第一行相同的结果值。

SELECT SUM(sodC.OrderQty*pawC.ListPrice) AS SubTotalC 
   FROM SalesOrderDetail sodC 
   JOIN ProductAW pawC 
   ON pawC.ProductID=sodC.ProductID
   GROUP BY sodC.SalesOrderID

OR

SELECT SUM(sodC.OrderQty*pawC.ListPrice) AS SubTotalC 
   FROM SalesOrderDetail sodC 
   JOIN ProductAW pawC 
   ON pawC.ProductID=sodC.ProductID
   GROUP BY sodC.SalesOrderID

6 个答案:

答案 0 :(得分:1)

这是最终解决方案:

SELECT 
   A.SalesOrderID,
   A.SubTotal AS SubTotalA,
   B.SubtotalB,
   C.SubtotalC 
FROM SalesOrderHeader A
JOIN
(
   SELECT SUM(sodB.OrderQty*sodB.UnitPrice) AS SubTotalB, sodB.SalesOrderID 
   FROM SalesOrderDetail sodB 
   JOIN ProductAW pawB 
   ON pawB.ProductID=sodB.ProductID
   GROUP BY sodB.SalesOrderID
)  AS B
ON A.SalesOrderID = B.SalesOrderID
JOIN
(
  SELECT SUM(sodC.OrderQty*pawC.ListPrice) AS SubTotalC, sodC.SalesOrderID 
  FROM SalesOrderDetail sodC 
  JOIN ProductAW pawC 
  ON pawC.ProductID=sodC.ProductID
  GROUP BY sodC.SalesOrderID
)  AS C
ON A.SalesOrderID = C.SalesOrderID

答案 1 :(得分:0)

您的外部查询没有任何ON子句。这将导致表B中的每条记录针对表A中的每条记录进行设置。因此,如果表A有5条记录,而表B有5条记录,则总共有25条记录。当然,所有这些记录也会与表C相乘。将针对表C中的每条记录设置所有AB记录。

我为每个子查询SELECT语句添加了一个ProductID,然后向外部查询中的每个JOINS添加了一个ON语句,以加入匹配的ProductID。我希望这就是你想要的。

SELECT 
   A.SalesOrderID,
   A.SubTotal AS SubTotalA,
   B.SubtotalB,
   C.SubtotalC 
FROM SalesOrderHeader A
JOIN
(
   SELECT SUM(sodB.OrderQty*sodB.UnitPrice) AS SubTotalB,
   pawB.ProductID
   FROM SalesOrderDetail sodB 
   JOIN ProductAW pawB 
   ON pawB.ProductID=sodB.ProductID
   GROUP BY sodB.SalesOrderID
)  AS B 
ON A.ProductID = B.ProductID
JOIN
(
   SELECT SUM(sodC.OrderQty*pawC.ListPrice) AS SubTotalC,
   pawC.ProductID
   FROM SalesOrderDetail sodC 
   JOIN ProductAW pawC 
   ON pawC.ProductID=sodC.ProductID
   GROUP BY sodC.SalesOrderID
 )  AS C
ON A.ProductID = C.ProductID

答案 2 :(得分:0)

我喜欢那个网站,但我希望有一个地方可以比较答案,因为我只想知道我的查询是否以最佳方式完成。这就是我提出的同样问题:

SELECT soh.salesorderid, soh.subtotal AS "SubTotal A", SUM(sod.orderqty * sod.unitprice) AS "SubTotal B", SUM(sod.orderqty * paw.ListPrice) AS "SubTotal C" FROM SalesOrderHeader soh JOIN SalesOrderDetail sod (ON sod.salesorderid = soh.salesorderid) JOIN ProductAW paw (ON paw.productid = sod.productid) GROUP BY soh.salesorderid

我还在学习,如果有人想要进入,让我知道如何改进它,请做。

答案 3 :(得分:0)

我们可以使用聚合函数和GROPING获得结果。使用MAX(Soh.SubTotal)考虑到SalesOrderHeader表中将只有一个唯一行。其余的计算可以在聚合函数内完成。

SELECT Soh.SalesOrderID
     , MAX(Soh.SubTotal) as SubTotal
     , COALESCE(SUM(Sod.OrderQty * Sod.UnitPrice), 0) as [Sum of OrderQty*UnitPrice]
     , COALESCE(SUM(Sod.OrderQty * Prd.ListPrice),0) as [Sum of OrderQty*ListPrice] 
FROM   SalesOrderHeader as Soh 
       INNER JOIN SalesOrderDetail as Sod ON (Soh.SalesOrderID = Sod.SalesOrderID)
       INNER JOIN Product as Prd ON (Prd.ProductID = Sod.ProductID)
GROUP BY Soh.SalesOrderID;

答案 4 :(得分:0)

这是正确的答案:

select soh.salesOrderId,soh.SubTotal,sum(sod.OrderQty*sod.UnitPrice), 
sum(sod.OrderQty*p.ListPrice) from SalesOrderHeader soh
inner join SalesOrderDetail sod on soh.SalesOrderId=sod.SalesOrderId
inner join Product p on p.ProductId=sod.productId
group by soh.salesOrderId,soh.SubTotal;

投票最高的答案是:

  1. 过于复杂
    • 不需要子查询,它们只是使查询更长的阅读时间
  2. 表现更差
    • 重复访问同一张表以搜索相同的行,只是处理方式不同。
  3. 不再从事冒险工作。
    • 没有名为“ ProductAw”的表,现在是“ Product”,我想可能是他们对其进行了更改

此解决方案与@Vishwanath Dalvi的负号相同(因为不需要使用合并)。 也和@AruN一样,这实际上只是对他的答案评论的回答(要求提供理由),因此这应该是对他的答案的评论。 不幸的是,我刚开始使用stackOverflow,无法发表评论:(

答案 5 :(得分:-1)

select t1.SalesOrderID ID,t1.SubTotal SUBTOTAL,
sum(t2.OrderQty*t2.UnitPrice) SUBTOTAL
,sum(t2.OrderQty*t3.ListPrice) SUBTOTAL
from SalesOrderHeader t1 join SalesOrderDetail t2 on t1.SalesOrderID=t2.SalesOrderID join ProductAW t3 on t3.productid=t2.productid
group by t1.SalesOrderID,t1.Subtotal