0

我正在使用谷歌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. 仅选择最近 26 个检查周
  4. 如果一个人缺少一周,则填写值 0 并将其包含在平均值中。

我尝试过这样的事情,但它是错误的:

 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与 columns 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)

在此处输入图像描述

4

3 回答 3

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
于 2013-06-25T19:07:44.027 回答
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 
于 2013-06-25T19:49:46.850 回答
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

于 2013-06-25T20:39:19.940 回答