在SQL Server的Northwind数据库中每个区域的总销售额?

时间:2013-07-29 14:00:20

标签: sql sql-server northwind

如何计算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];

如果你运行这些查询,你会发现第三笔金额不等于第一笔金额!这意味着我们在每个地区都有一些重复记录!

3 个答案:

答案 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
  1. EmployeeSales :每位员工的总销售额。
  2. EmployeeRegion :为每位员工找到regionID
  3. 最后 ,分组依据RegionID并使用SUM()功能查找每个地区的总销售额。 Result