我有一个带有Flag列的表,它可以是true / false。 我想对行进行分组并计算列Val的平均值,如下图所示:
来源表和期望结果
答案 0 :(得分:3)
您可以使用派生表和窗口函数执行此操作:
declare @t table(ID int,Val decimal(10,2),Flag bit);
insert into @t values (515,5.4,0),(516,1,1),(517,0,0),(518,0,0),(519,3,0),(520,7,0),(521,8,0),(522,2,0),(523,5,0),(524,3,1),(525,1,0),(526,2,0),(527,3,0),(528,2,0),(529,8,0),(530,9,0),(531,0,0),(532,4,1),(533,0,0),(534,2,0),(535,1,0),(536,0,0),(537,0,1),(538,1,0);
with c as
(
select ID
,Val
,Flag
,sum(cast(Flag as int)) over (order by ID) as rn
from @t
)
select cast(min(ID) as nvarchar(10)) + ' to ' + cast(max(ID) as nvarchar(10)) as IDRange
,avg(Val) as AverageVal
from c
group by rn
order by rn;
输出:
+------------+------------+
| IDRange | AverageVal |
+------------+------------+
| 515 to 515 | 5.4 |
| 516 to 523 | 3.25 |
| 524 to 531 | 3.5 |
| 532 to 536 | 1.4 |
| 537 to 538 | 0.5 |
+------------+------------+
这利用递归来获得正在运行的分组,因此可以改进,但会得到你想要的结果:
declare @t table(ID int,Val decimal(10,2),Flag bit);
insert into @t values (515,5.4,0),(516,1,1),(517,0,0),(518,0,0),(519,3,0),(520,7,0),(521,8,0),(522,2,0),(523,5,0),(524,3,1),(525,1,0),(526,2,0),(527,3,0),(528,2,0),(529,8,0),(530,9,0),(531,0,0),(532,4,1),(533,0,0),(534,2,0),(535,1,0),(536,0,0),(537,0,1),(538,1,0);
with t as
(
select ID
,Val
,Flag
,row_number() over (order by ID) as rn
from @t
),c as
(
select ID
,Val
,Flag
,rn
,0 as g
from t
where rn = 1
union all
select t.ID
,t.Val
,t.Flag
,t.rn
,c.g + cast(t.Flag as int) as g
from t
join c
on t.rn = c.rn+1
)
select cast(min(ID) as nvarchar(10)) + ' to ' + cast(max(ID) as nvarchar(10)) as IDRange
,avg(Val) as AverageVal
from c
group by g
order by g;