从过去26个条目中获取平均值

时间:2013-06-25 18:44:02

标签: sql sql-server

我正在使用Google jsapi来绘制面积图,所以我必须得到两个不同的平均值。

第一个是针对特定的人,第二个是整个公司,除了那个人。

我正在使用此查询来指定指定人员的最后26周。

 SELECT TOP 26 DATE_GIVEN
 FROM CHECKS
 WHERE PERSON_NO='001'
 ORDER BY DATE_GIVEN DESC

但是我需要修改它以获得过去26周,即使该人跳过一周,并且在缺失的几周内填写0并将其包含在平均值中。

但第二个是超级硬,我不知道该怎么做。这就是我想要做的事情:

  1. 选择表格中所有期望为person_no = 001
  2. 的检查
  3. 每周对所有人进行分组
  4. 仅选择最后26个检查周
  5. 如果某人缺少一周,请填写值0并将其包含在平均值中。
  6. 我试过这样的事情,但这是错的:

     SELECT TOP 26 AVG(CHECK_AMOUNT) AS W2
     FROM CHECKS
     WHERE NOT PERSON_NO='001'
     GROUP BY Datepart(week,DATE_GIVEN)
     ORDER BY DATE_GIVEN DESC
    

    让它更清晰一点:

    我试图获得一个人的每周平均值,而不包括那个人的公司其他人的平均值。表名为CHECKS,列CHECK_NO, DATE_GIVEN, AMOUNT, PERSON_NO

    我也尝试过这样的事情,但我不知道这是否正确:

    SELECT TOP 26 AVG(CHECK_AMOUNT) AS W1
    FROM CHECKS
    WHERE PERSON_NO='001'
    GROUP BY Datepart(week, DATE_GIVEN)
    
    SELECT TOP 26 AVG(CHECK_AMOUNT) AS W2
    FROM CHECKS
    WHERE NOT PERSON_NO='001'
    GROUP BY Datepart(week, DATE_GIVEN)
    

    enter image description here

3 个答案:

答案 0 :(得分:2)

您想在子查询中执行top,然后执行平均值:

select avg(check_amount) as w1
from (SELECT TOP 26 c.*
      FROM CHECKS
      WHERE PERSON_NO='001'
      ORDER BY DATE_GIVEN DESC 
     ) c

答案 1 :(得分:1)

我认为它应该是这样的:

SELECT TOP 26 *
FROM (
    SELECT TOP 100 PERCENT AVG(check_amount) AS W2, DATE_GIVEN
    FROM Checks
    WHERE PERSON_NO='001'
    GROUP BY DATE_GIVEN    
    ORDER BY 2 DESC
) Top_26 

答案 2 :(得分:1)

第一个。 由于您需要获取过去26周的数据,因此您需要从当前日期减去26周。由于你希望在错过的几周内包含0,所以与26岁时你所得到的总和相同。

Declare @weeks int = 26;

SELECT sum(CHECK_AMOUNT)/@weeks FROM CHECKS 
WHERE PERSON_NO='001'  and DATE_GIVEN >= dateadd(ww, -@weeks, getdate())

对于公司的其余部分:(i)在过去26周内,除了您的人之外,每个人都要获得平均支票; (ii)获得这些平均值的平均值(此处不需要为失踪人员设置0)

select avg (Person_Check_Amount) from
    (
    SELECT PERSON_NO, SUM(CHECK_AMOUNT)/@weeks 
         as Person_Check_Amount
    FROM CHECKS 
    WHERE PERSON_NO <> '001'  and DATE_GIVEN >= dateadd(ww, -@weeks, getdate())
    GROUP BY PERSON_NO
    ) t

<强>更新

我添加了/COUNT (distinct PERSON_NO),因为公司的人数从一周到另一周不等。

现在我们可以将这些查询组合在一起,以便进行比较。它可以在单个查询中完成。

使用公用表表达式,使逻辑更加可见。在这里,我将DATEPART更改为DATEDIFF,因此当我们回到上一年时,我们会计算从今天起的周数(25,26,... 58,59 ...),而不是周数这一年(如52)

DECLARE @weeks int = 26

;WITH Person AS (
   SELECT
     datediff(ww, DATE_GIVEN, getdate())+1 AS Week,
     AVG(CHECK_AMOUNT) AS Person_Check_Amount
   FROM CHECKS
   WHERE PERSON_NO=11  AND DATE_GIVEN >= dateadd(ww, -@weeks, getdate())
   GROUP BY datediff(ww, DATE_GIVEN, getdate()) +1
)

, Company AS (
    SELECT week,
  AVG (COMPANY_Check_Amount) AS COMPANY_Check_Amount
    FROM (
       SELECT
         datediff(ww, DATE_GIVEN, getdate())+1 AS Week,
         SUM(CHECK_AMOUNT)/COUNT(DISTINCT PERSON_NO) AS COMPANY_Check_Amount
       FROM CHECKS
       WHERE PERSON_NO<>11  AND DATE_GIVEN >= dateadd(ww, -@weeks, getdate())
       GROUP BY datediff(ww, DATE_GIVEN, getdate())+1 
    ) t
  GROUP BY Week
)

SELECT c.week
 , isnull(Person_Check_Amount,0)  Person_Check_Amount
 , isnull(Company_Check_Amount,0) Company_Check_Amount
FROM Person p
FULL OUTER JOIN Company c ON c.week = p.week
ORDER BY Week DESC

<强> SQLFiddle