Sql 在较低晶粒度下计算,并向上轧制至较高晶粒度

Sql 在较低晶粒度下计算,并向上轧制至较高晶粒度,sql,sql-server,Sql,Sql Server,我正在重新设计一些遗留代码,遇到了这个计算。想知道这里是否有人能指出这样做的理由是什么?作者已不在公司,也没有任何文件 上下文是:如果员工类型定义为最低粒度,则首先在该级别计算加权平均值,然后通过重新计算加权平均值,将其汇总为更高的粒度 employee department employee_type salary weight location A X F 1000 3.15 boston B

我正在重新设计一些遗留代码,遇到了这个计算。想知道这里是否有人能指出这样做的理由是什么?作者已不在公司,也没有任何文件

上下文是:如果员工类型定义为最低粒度,则首先在该级别计算加权平均值,然后通过重新计算加权平均值,将其汇总为更高的粒度

employee department employee_type   salary   weight   location
  A        X           F             1000      3.15    boston
  B        X           P              300      1.27     NY
  C        Y           F             2000      3.38     Tampa
  D        Y           P                       1.12     LA
  E        X           F              3000     3.38     SFO
用于计算部门平均工资的查询:

     select department, sum(case when avg_salary is not null then 
      avg_salary*bonus else 0 end)/sum(case when avg_salary is not null then 
     bonus else 1 end)
   from 
     (select employee,department,location,employee_type
    ,sum(weight) as bonus
    ,sum(case when salary is not null then salary*weight else 0 end)/sum(case when salary is not null then weight else 1 end) as avg_salary
    from employee
    group by employee,department,location,employee_type
    )x
    group by  department
输出:

      X 1752.69230769231
      Y 1502.22222222222
如果我们以最低的粒度进行聚合,然后以较高的粒度计算平均工资,显然会得到不同的值


所以我想问题是,哪种方法是正确的,这种方法背后的基本原理是什么?它只是为了考虑缺失值吗?

这是一个简单的加权平均值。(在Excel中思考SumProduct)

您可能会注意到分母中的NULLIF()。这是为了避免可怕的除以零。我相信您知道,但是您可以通过字段的任何组合进行分组(从原子级别一直到更高)

示例

Declare @YourTable Table ([employee] varchar(50),[department] varchar(50),[employee_type] varchar(50),[salary] money,[weight] money,[location] varchar(50))
Insert Into @YourTable Values
 ('A','X','F',1000,3.15,'boston')
,('B','X','P',300,1.27,'NY')
,('C','Y','F',2000,3.38,'Tampa')
,('D','Y','P',null,1.12,'LA')
,('E','X','F',3000,3.38,'SFO')

Select Department
      ,WeigtedAvg = sum(Salary*Weight)/NullIf(sum(Weight),0)
 From  @YourTable
 Group By Department
返回

Department  WeigtedAvg
X           1752.6923
Y           1502.2222
Department  WeigtedAvgBonus WeigtedAvgRate
X           1752.6923       3.1793
Y           1502.2222       3.38 -- Notice this matches the only non-null observation in Y
只是为了好玩

Select Department
      ,WeigtedAvgBonus = sum(Salary*Weight)/NullIf(sum(Weight),0)
      ,WeigtedAvgRate  = sum(Salary*Weight)/NullIf(sum(Salary),0)
 From  @YourTable
 Group By Department
返回

Department  WeigtedAvg
X           1752.6923
Y           1502.2222
Department  WeigtedAvgBonus WeigtedAvgRate
X           1752.6923       3.1793
Y           1502.2222       3.38 -- Notice this matches the only non-null observation in Y

谢谢是的,我也有同样的想法——一个简单的按部门分组并计算加权平均数。但你知道目前如何实施该计划的理由是什么吗?我能想到的另一件事是,在此之前的消息来源是在SAS。也许是逻辑的1:1副本?@Bee我猜作者是有机地做的。。。一步一个脚印从原子开始。情况更糟。