2

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

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

如果您运行这些查询,您会看到第三个总和不等于第一个!这意味着我们在每个地区都有一些重复记录!

4

3 回答 3

1

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

您必须先使用子查询GROUP BY来查找RegionID每个 Employee,然后加入它而不是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

此外,您不应该使用已经过时 20 多年的旧式 JOINS。

于 2013-07-29T14:25:15.263 回答
0

如果不了解您的表格,很难给您一个可靠的答案,但是您的查询看起来可以被清理。看看 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,这种表就可以工作。就这么简单。

让我知道它是如何工作的或分享更多信息。谢谢!

于 2013-07-29T14:24:23.090 回答
0

您可以使用CTE(通用表表达式)来解决此问题。

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. EmployeeRegionregionID为每个 Employee 查找。
  3. 最后,通过 Group ByRegionID和使用SUM()函数来查找每个区域的总销售额。 结果
于 2016-03-04T22:41:01.923 回答