【问题标题】:Total sales of each region in Northwind database of SQL Server?SQL Server 的 Northwind 数据库中每个区域的总销售额?
【发布时间】:2013-07-29 14:00:19
【问题描述】:

我如何计算SQL ServerNorthwind数据库中每个地区的总销售额? 我已经运行了以下查询:

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];

如果您运行这些查询,您会发现第三个总和不等于第一个!说明我们每个地区都有一些重复记录!

【问题讨论】:

  • 使用内连接避免重复

标签: sql sql-server northwind


【解决方案1】:

在表EmployeeTerritories 中,一个员工可以拥有更多地区,因此当您加入该表时,您会将每个员工的所有记录相乘 - 即使每个员工的所有地区都属于单个地区。

您必须使用带有GROUP BY 的子查询首先为每个员工查找RegionID,然后加入该EmployeeTerritories 而不是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.

【讨论】:

    【解决方案2】:

    如果不了解您的表格,很难给您一个可靠的答案,但您的查询看起来可以被清理。看看 INNER JOIN。它们将成倍地简化您的生活。隐式连接很难阅读和调试(你用括号做什么),而显式连接非常容易阅读。学习也不需要很长时间:

    http://www.w3schools.com/sql/sql_join_inner.asp

    如果您按地区跟踪销售额,您的表格应该相同,以防止重复出现。否则你很快就会做噩梦。此外,如果唯一的变量是区域,您应该能够使用相同的查询来提取区域信息。像这样的东西应该就是你所需要的:

    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=?
    

    再一次,我没有看到你的桌子,所以我不得不相信你的订单详细信息列表中有员工 ID。您需要一种方法来连接该表,该表链接到您已经在数据库中建立的表。这就是我建议 INNER JOIN 的原因...它们会让您更轻松地查看表结构并帮助您更快地进行调试。只需输入一个新的 regionID,这种表就可以工作。就这么简单。

    让我知道它的工作原理或分享更多信息。谢谢!

    【讨论】:

      【解决方案3】:

      你可以使用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:为每个 Employee 查找 regionID
      3. 最后,Group By RegionID 并使用SUM() 函数查找每个地区的总销售额。 Result

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2013-11-24
        • 1970-01-01
        • 2022-12-18
        • 1970-01-01
        • 2014-07-06
        相关资源
        最近更新 更多