【问题标题】:SQL calculations: Perform AVERAGE using THIS year, LAST year and NEXT year data?SQL 计算:使用今年、去年和明年的数据执行平均?
【发布时间】:2011-05-18 10:08:24
【问题描述】:

我正在努力在 SQL 中重新创建可以在 Excel 中执行的特定计算。它涉及平均值。

我们收集多年的数据。我们创建的一张表是三年平均值。以下表格显示:1) RAW 数据,以及 2) 包含 AVERAGE 数据的新表格。 “维度”是 [年份] 和 [项目代码]。

平均数据基于一年数据的平均值,两边均为 2 年。即 1991 年平均数字 = 平均 (1990,1991,1992)。 =平均(B2:D2)

1) 原始

2) 平均

alt text http://tinypic.com/images/404.gif

在 Excel 中,这似乎很简单:一个平均公式,然后拖到其他单元格中,或者在 VBA 中使用 R1C1 引用。

但是在 SQL 中它是什么? 你怎么说使用“今年”和前年和后年的数据?

另外,我意识到如果有一个空单元格它会抛出我的计算,那么你如何管理 NULL 值以便它只在有三个数字要使用时计算?......然后再做一遍直到完成(很多年,很多很多的ItemCodes)

任何帮助将不胜感激。

【问题讨论】:

  • 您使用的是什么 SQL 数据库?到目前为止,您提出了哪些疑问,它们有什么问题?可以发一下代码吗?
  • 还有,数据库的格式是什么?
  • 分享您尝试过的查询!
  • 数据库是公司定制的数据库,对后端(计算)的访问有限。它有一些预定义的函数:求和、平均等,我们可以在其中使用参数。
  • 我还没有尝试任何复杂的计算,所以我没有任何东西可以展示。我们目前正在使用它来执行以下操作:(Arg1/Arg2)*100;或 IF 'ItemCode' in ('A123', 'B123') THEN (Arg1 + Arg3) / Arg2 * 100 ELSE Arg1 / Arg2 * 100。目前相当基本的东西,因此我请求关于如何更复杂的查询的建议会看。谢谢。

标签: sql database


【解决方案1】:

我在下面创建了一个示例,我在其中平均了 1994 年的值,以帮助您入门。 SQL 查询应该在任何 RDBMS 中工作。也就是说,如果您可以使用供应商特定的功能,每个数据库都有更好的方法。例如,使用 Oracle 分析,您可以计算滚动平均值并非常像想要的那样访问上一行/下一行。

drop table t;

create table t(
   item_code varchar(10) not null
  ,year      int not null
  ,figure    decimal(5,2) not null
  ,primary key(year, item_code)
);

insert into t(item_code, year, figure) values('A', 1990, 5);
insert into t(item_code, year, figure) values('A', 1991, 7.2);
insert into t(item_code, year, figure) values('A', 1992, 9.2);
insert into t(item_code, year, figure) values('A', 1993, 12.5);
insert into t(item_code, year, figure) values('A', 1994, 10);
insert into t(item_code, year, figure) values('A', 1995, 9);

insert into t(item_code, year, figure) values('B', 1990, 16);
insert into t(item_code, year, figure) values('B', 1991, 17);
insert into t(item_code, year, figure) values('B', 1992, 10);
insert into t(item_code, year, figure) values('B', 1993, 13);
insert into t(item_code, year, figure) values('B', 1994, 15.5);
insert into t(item_code, year, figure) values('B', 1995, 12);

insert into t(item_code, year, figure) values('C', 1990, 4);
insert into t(item_code, year, figure) values('C', 1991, 9);
insert into t(item_code, year, figure) values('C', 1992, 15);
insert into t(item_code, year, figure) values('C', 1993, 12);
insert into t(item_code, year, figure) values('C', 1994, 10);
insert into t(item_code, year, figure) values('C', 1995, 7.2);



select item_code
      ,1994 as year
      ,sum(case when year = 1995 then figure else 0 end) as next_year
      ,sum(case when year = 1994 then figure else 0 end) as this_year
      ,sum(case when year = 1993 then figure else 0 end) as prev_year
      ,sum(figure) / count(*) as avg
  from t
 where year in(1993, 1994, 1995)
 group 
    by item_code
having count(*) = 3;

count(*) = 3 满足只有在三年可用时才会计算平均值的约束。显然,您必须用一些变量替换常量。此外,该查询仅计算 1 年的平均值。

【讨论】:

  • @Mike,你最后用了吗?
【解决方案2】:

你没有说明技术,假设是 MSSQL。

假设我的日期是 2010 年

SELECT dateadd(Year, -1, mydate), mydate, dateadd(Year, 1, mydate) 
   FROM SomethingOrOther

返回

2009, 2010, 2011

DATEADD documentation

假设x、y、z都为NULL

SELECT COALESCE(x, y, z, 0)

返回

0

COALESCE documentation

【讨论】:

  • 感谢您的建议。我有一些阅读要做。我需要询问我们的 IT 人员,我们是否可以访问 dateadd 或 COALESCE 等功能。可能是他们必须在后端执行此查询并将其提供给我。你的目标是通过向他们展示查询的结构来推动他们实现这一目标。
猜你喜欢
  • 1970-01-01
  • 2018-12-13
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2023-03-16
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多