2016-11-20 38 views
0

我有一个表格数据库由以下字段组成: ID,资历(年数),结果和一些其他不太重要的字段。 表列例如:使用高级组编写查询

ID:36  Seniority(years):1.79 outcome:9627 

我需要写在相对简单的代码查询(SQL Server)的返回的平均结果,由资历场分组,用五年的跨越式(0-5岁,6 -10等),条件是只有组数超过3行才显示平均值。

结果行例如:

range:0-5 average:xxxx 

非常感谢您

+0

这不是一个代码编写的服务。你到目前为止尝试了什么?发布您的代码!当你运行它时发生了什么?你预期会发生什么?你有什么特别的问题? https://stackoverflow.com/help/mcve – Robert

+0

你是国王吗?我没有投票给你...... –

回答

0

这将是这样的:

select floor(seniority/5), avg(outcome) 
from t 
group by floor(seniority/5) 
having count(*) >= 3; 

注:这打破了论资排辈分成相等大小的组是0〜 4,5-9等等。这比拥有不平等的群体似乎更合理。

+0

不会工作......'1.79/5 = 0.358000'。我想你需要投入int。 –

+0

@GiorgiNakeuri。 。 。谢谢。我很习惯SQL Server做整数除法,因此我错过了简单的观察:'资历'不是一个整数。 –

1

使用CASE声明创建不同的年龄段。试试这个

select case when Seniority between 0 and 5 then '0-5' 
      when Seniority between 6 and 10 then '6-10' 
      .. 
     End, 
     Avg(outcome) 
From yourtable 
Group by case when Seniority between 0 and 5 then '0-5' 
      when Seniority between 6 and 10 then '6-10' 
      .. 
     End 
Having count(1)>=3 

既然你有小数,如果你想数5.40-5组和5.66-10然后在CASE语句中使用Round(Seniority,0),而不是Seniority

+0

我喜欢这个想法,因为我需要保持简单,不需要创建更多的表格。但是有没有办法更有效地将它分组?因为如果我的MAX资历是60我需要写12个案例,如果我有大量的行,并且我不知道MAX资历 – user7185817

0

您可以按照戈登的回答(但你应该稍微修改一下),但我会在所有可能的时间间隔内使用附加表格来完成此操作。然后您可以添加适当的索引来提升它。

create table intervals 
(
    id int identity(1, 1), 
    start int, 
    end int 
) 

insert into intervals values 
(0, 5), 
(6, 10) 
... 


select i.id, avg(t.outcome) as outcome 
from intervals i 
join tablename t on t.seniority between i.start and i.end 
group by i.id 
having count(*) >=3 

如果创建新表是不是一种选择,你可以随时使用CTE

;with intervals as(
        select * from 
        (values 
          (0, 5), 
          (6, 10) 
          --... 
        ) t(start, [end]) 
       ) 
select i.id, avg(t.outcome) as outcome 
from intervals i 
join tablename t on t.seniority between i.start and i.[end] 
group by i.id 
having count(*) >=3 
0

附: 0-5包含6个值,而6-10含有5.


select  'range:' 
      + cast (isnull(nullif(floor((abs(seniority-1))/5)*5+1,1),0) as varchar) 
      + '-' 
      + cast ((floor((abs(seniority-1))/5)+1)*5 as varchar)  as seniority_group 

      ,avg(outcome) 

from  t 

group by floor((abs(seniority-1))/5) 

having  count(*) >= 3 
;