如何计算SQL Server Northwind
数据库中每个区域的总销售额?
我跑了下面的查询:
1)
select sum( od.Quantity * od.UnitPrice ), v.rid from
Orders o , [Order Details] od , (select et.EmployeeID eid, r.RegionID rid from region r, territories t , EmployeeTerritories et
where r.RegionID = t.RegionID and et.TerritoryID = t.TerritoryID ) v
where od.OrderID = o.OrderID and v.eid = o.EmployeeID
group by v.rid;
2)
select sum(b) from
(select sum(aa.UnitPrice * aa.Quantity) b
from region r, territories t , EmployeeTerritories et ,
(select o.EmployeeID , od.Quantity , od.UnitPrice from
Orders o , [Order Details] od
where od.OrderID = o.OrderID ) aa
where
t.regionid = r.regionid and
et.TerritoryID = t.TerritoryID and
et.EmployeeID = aa.EmployeeID
group by r.RegionID) x;
3)
select sum (Quantity * UnitPrice) from [Order Details];
如果你运行这些查询,你会发现第三笔金额不等于第一笔金额!这意味着我们在每个地区都有一些重复记录!
答案 0 :(得分:1)
在表EmployeeTerritories
中,一个员工可以拥有更多地区,因此当您加入时,您可以将每个员工的所有记录相乘 - 即使每个员工的所有地区都属于单个地区。
您必须先使用GROUP BY
的子查询为每个员工查找RegionID
,然后加入EmployeeTerritories
您的查询A
WITH CTE_EmpRegion AS
(
SELECT EmployeeID, MAX(RegionID) RegionID
FROM dbo.EmployeeTerritories et
INNER JOIN territories t ON t.TerritoryID = et.TerritoryID
GROUP BY EmployeeID
)
SELECT RegionID, SUM(Quantity * UnitPrice)
FROM Orders o
INNER JOIN [Order Details] od ON o.OrderID = od.OrderID
INNER JOIN CTE_EmpRegion er ON o.EmployeeID = er.EmployeeID
GROUP BY RegionID
Also you should not be using old-style JOINS which are outdated for more than 20 years now.
答案 1 :(得分:0)
如果不了解您的表格,很难给出一个可靠的答案,但您的查询看起来似乎可以清理。看看INNER JOINs。它们将以指数方式简化您的生活。隐式连接很难读取和调试(你用括号做什么),而显式连接非常容易阅读。学习它不需要很长时间:
http://www.w3schools.com/sql/sql_join_inner.asp
如果您按区域跟踪销售额,则表格应相同,以防止重复出现。否则你很快就会有一场噩梦。此外,如果唯一的变量是region,则应该能够使用相同的查询来提取区域信息。这样的事情应该是你所需要的:
SELECT SUM(od.Quantity * od.UnitPrice) total_sales FROM [Order Details] od
INNER JOIN Orders o ON o.orderID = od.orderID
INNER JOIN EmployeeTerritories et ON et.employeeID=od.employeeID
INNER JOIN Regions t ON t.regionID = et.regionID
INNER JOIN Territories t ON t.regionID = r.regionID
WHERE t.regionID=?
同样,我还没有看到你的桌子,所以我必须在你的订单明细清单中对你有employeeID的信念进行一次飞跃。您需要一种方法来连接该表,该表链接到您已在数据库中建立的表。这就是为什么我建议INNER JOINs ...它们会让你更容易看到表结构,并帮助你更快地调试。只需要输入一个新的regionID,这种表就可以了。那很简单。
让我知道它的工作原理或分享更多信息。谢谢!
答案 2 :(得分:0)
您可以使用CTE (Common Table Expression)来解决此问题。
USE Northwind;
GO
WITH EmployeeSales
AS ( SELECT e.EmployeeID ,
e.LastName ,
SUM(od.Quantity * od.UnitPrice) ESales
FROM dbo.Employees AS e
INNER JOIN dbo.Orders AS o ON e.EmployeeID = o.EmployeeID
INNER JOIN dbo.[Order Details] AS od ON o.OrderID = od.OrderID
GROUP BY e.EmployeeID ,
e.LastName
),
EmployeeRegion
AS ( SELECT DISTINCT
EmployeeID ,
r.RegionID ,
RegionDescription
FROM dbo.Region AS r
INNER JOIN dbo.Territories AS t ON r.RegionID = t.RegionID
INNER JOIN dbo.EmployeeTerritories AS et ON t.TerritoryID = et.TerritoryID
)
SELECT EmployeeRegion.RegionID ,
EmployeeRegion.RegionDescription ,
SUM(EmployeeSales.ESales) RegionTotalSale
FROM EmployeeSales
INNER JOIN EmployeeRegion ON EmployeeSales.EmployeeID = EmployeeRegion.EmployeeID
GROUP BY EmployeeRegion.RegionID ,
EmployeeRegion.RegionDescription
regionID
。RegionID
并使用SUM()
功能查找每个地区的总销售额。
Result