计算Top n与SQL Group By相结合的平均值

时间:2015-01-06 14:16:32

标签: sql ms-access join group-by subquery

这是一个非常假设的例子,我加入了两个表(ORDERS和ORDHIST)。我正在使用MS-ACCESS 2010.我正在尝试编写一个连接或子查询,它将返回两位销售人员的日期前2个订单的平均值。 订单
SalesPersonID 订单ID 价值
1 123 100
1 124 30
1 125 55
2 126 80
2 127 20
1 128 45
2 129 60
2 130 35

ORDHIST
的OrderID 日期
123个22/03/2011
125个25/03/2011
127个29/03/2011
124个24/03/2011
126个26/03/2011
128个30/03/2011
129个30/03/2011
130 01/04/2011

我有SQL列出按 SalesPersonID 日期排序的记录:

SELECT Orders.SalesPersonID, Orders.OrderID, Orders.Value, OrdHist.Date 
  FROM Orders 
  INNER JOIN OrdHist ON Orders.OrderID = OrdHist.OrderID 
  ORDER BY Orders.SalesPersonID, OrdHist.Date DESC;
SalesPersonID OrderID  Value   Date  
1              128       45    30/03/2011  
1              125       55    25/03/2011  
1              124       30    24/03/2011  
1              123      100    22/03/2011  
2              130       35    01/04/2011  
2              129       60    30/03/2011  
2              127       20    29/03/2011  
2              126       80    26/03/2011  

所以我现在想为每个SalesPerson选择前两行,并显示两者的平均值以给出我正在寻找的最终结果:

SalesPersonID   LatestAvg
1               50
2               47.5

我是编写联接和内部查询的新手,我不能超越SalesPerson为所有订单提取平均值

SELECT Orders.SalesPersonID, Avg(Orders.Value) AS AvgOfValue 
  FROM Orders 
  INNER JOIN OrdHist 
  ON Orders.OrderID = OrdHist.OrderID 
  GROUP BY Orders.SalesPersonID;
SalesPersonID   AvgOfValue
1               57.5
2               48.75

但这并不是在群组中最近的2个日期进行过滤,因此任何有关如何在子查询中进行选择或创建其他联接的指导都将非常受欢迎

2 个答案:

答案 0 :(得分:1)

这是使用的最终SQL语句

SELECT SalesPersonID, AVG(Value) As AvgOfValue FROM (
  SELECT Orders.SalesPersonID, Orders.Value 
FROM ((Orders 
INNER JOIN OrdHist ON Orders.OrderID = OrdHist.OrderID) 
INNER JOIN Orders o2 on o2.SalesPersonId = Orders.SalesPersonId)
INNER JOIN OrdHist oh2 on oh2.OrderID = o2.OrderID and oh2.Date >= OrdHist.Date 
GROUP BY Orders.SalesPersonID, Orders.OrderID, Orders.Value 
HAVING COUNT(*) <= 2
) t1 GROUP BY SalesPersonID

答案 1 :(得分:0)

您可以使用自联接仅为每个销售人员获取前2行,并使用派生表将这些行分组为其平均值。

SELECT SalesPersonID, AVG(Value) As AvgOfValue FROM (
  SELECT Orders.SalesPersonID, Orders.Value
  FROM Orders 
  INNER JOIN OrdHist ON Orders.OrderID = OrdHist.OrderID
  INNER JOIN Orders o2 on o2.SalesPersonId = Orders.SalesPersonId
  INNER JOIN OrderHist oh2 on oh2.OrderID = o2.OrderID and oh2.Date <= Orders.Date
  GROUP BY Orders.SalesPersonID, Orders.OrderID, Orders.Value
  HAVING COUNT(*) <= 2
) t1 GROUP BY SalesPersonID