获得间隔加权平均值的总和

时间:2017-09-14 08:09:45

标签: sql vba ms-access

首先,我正在使用Microsoft Access 2002-2003并在VBA中使用查询。这意味着如果可能,我需要一个完整的SQL字符串,我可以从VBA插入自定义间隔边界。

我有一张包含这种布局的表格:

   Date   | Value  
1.1.2010      1  
1.1.2012      2  
1.1.2015      3

我需要一个SQL查询来获取变量Interval中值的加权平均值。

这个想法是值从一个日期应用到下一个日期,因此值1例如适用于1.1.2010到31.12.2011,依此类推。
可变间隔可以(并且大部分时间)切入这些,所以如果我的间隔是从2010年7月1日到2012年1月17日,我需要考虑1.7.2010 - 2011年12月31日和1.1.2012 - 1.7.2012
如果Interval在第一个Date之前开始,则使用第一个Date的值。

两个例子:
1.1.2010 - 31.12.2012 - > (2 * 1 + 2)/ 3 = 1。33(1年2年和2年中的一年)
1.1.2008 - 1.7.2012 - > (4 * 1 + 0.5 * 2)/ 4.5 = 1.11(4年中的1年和2年中的一半)

我最大的问题是获得这些多个间隔(特别是使用自定义间隔),如果间隔在第一个日期之前开始,则将值设置为默认值。

我当前的查询:

SELECT SUM(t2.Value * DateDiff("d",t2.date,t1.date)) AS s1, 
       SUM(DateDiff("d",t2.date,t1.date)) AS s2, s1 / s2 AS s3
FROM table AS t1,
     table AS t2
WHERE t2.date < t1.date
  AND NOT Exists (SELECT t3.date, t4.date
                  FROM table AS t3,
                       table AS t4
                  WHERE t1.date = t3.date AND t4.date <> t2.date
                    AND t4.date > t2.date AND t4.date < t1.date
                    AND t2.date < t1.date e);

这给了我这样的东西:

s1                  |      s2      |    s3
730 * 1  + 1096 * 2    730 + 1096      s1/s2

s1是三个日期(2010-2012,2012-2015)之间的间隔的加权和 s2是这两个区间(5年)的和 然后s3是加权平均值。

查询通过将表加倍,得到所有小于另一个的日期,然后删除具有NOT EXISTS

的区间中日期的日期来获取所有间隔

现在我只需要将间隔界限“添加”到等式中......

我现在的查询仅适用于该表 但我需要一个Interval: 当前输出:

s1      |     s2    |   s3  
2922         1826       1.6

所需输出,示例间隔为1.1.2008 - 2016年12月31日:

   s1        |    s2    |    s3  
   ~5841       3287      5841/3287`  

间隔期为1.1.2008 - 2011年12月31日,分别为1,1.1.2012 - 2014年12月31日,分别为2和1.1.2015 - 2016年12月31日

1 个答案:

答案 0 :(得分:1)

我已彻底重写了您的查询,添加了参数,并使用了参数而不是t2的最低日期和t1的最高日期。

请注意,我已避免使用DateTableValue这两个字,因为它们是SQL关键字,不能用于表名或列名。

立刻要经历一段时间,但如果您有具体问题,我会回答。

请注意,如果要通过VBA执行此查询,则必须先设置参数。

PARAMETERS startInterval DateTime, endInterval DateTime;
SELECT SUM(t2.Weight *(IIF(t1.theDate IS NULL, endInterval, t1.theDate) - IIF(t2.theDate = (SELECT Min(theDate) FROM theTable), startInterval, t2.theDate))) AS s1, 
       SUM(IIF(t1.theDate IS NULL, endInterval, t1.theDate)  - IIF(t2.theDate = (SELECT Min(theDate) FROM theTable), startInterval, t2.theDate)) AS s2, s1 / s2 AS s3
FROM theTable AS t1 RIGHT JOIN 
     theTable AS t2 ON t2.theDate < t1.theDate
WHERE t1.theDate = (SELECT Min(t3.theDate) FROM theTable t3 WHERE t3.theDate > t2.theDate) OR t1.theDate IS NULL