我有一个查询,我获得每行的平均值并显示员工。 我希望它显示每位员工的平均值。意思是我想平均所有与同一员工的行。
我怎样才能做到这一点?
这是我目前的查询:
SELECT
(
SELECT AVG(rating)
FROM (VALUES
(cast(c.rating1 as Float)),
(cast(c.rating2 as Float)),
(cast(c.rating3 as Float)),
(cast(c.rating4 as Float)),
(cast(c.rating5 as Float))
) AS v(rating)
WHERE v.rating > 0
) avg_rating, employee
From CSEReduxResponses c
Where
month(c.approveddate)= 6
AND year(c.approveddate)=2014
下面我有一些我创建的示例数据:
create table CSEReduxResponses (rating1 int, rating2 int, rating3 int, rating4 int, rating5 int,
approveddate datetime,employee int)
insert into CSEReduxResponses (rating1 , rating2 ,rating3 , rating4 , rating5 ,
approveddate, employee )
values
(5,4,5,1,4,'2014-06-18',1),
(5,4,5,1,4,'2014-06-18',1),
(5,4,5,1,0,'2014-06-18',1),
(5,4,0,1,4,'2014-06-18',2),
(5,4,5,1,4,'2014-06-18',2),
(5,4,0,1,4,'2014-06-18',3),
(5,0,5,4,4,'2014-06-18',3),
(5,4,5,0,0,'2014-06-18',3);
答案 0 :(得分:0)
这样的事情怎么样?
select employee,
avg(case when n.n = 1 and rating1 > 0 then rating1
when n.n = 2 and rating2 > 0 then rating2
when n.n = 3 and rating3 > 0 then rating3
when n.n = 4 and rating4 > 0 then rating4
when n.n = 5 and rating5 > 0 then rating5
end)
from CSEReduxResponses c cross join
(select 1 as n union all select 2 union all select 3 union all select 4 union all select 5
) n
where month(c.approveddate)= 6 and year(c.approveddate)=2014
group by employee;
我建议将where
子句重写为:
where c.approveddate >= '2014-06-01' and c.approveddate < '2014-07-01'
这将允许SQL引擎在approveddate
上使用索引。
答案 1 :(得分:0)
select
(sum(rating1)+sum(rating2)+sum(rating3)+sum(rating4)+sum(rating5))
/
(count(nullif(rating1,0))+count(nullif(rating2,0))+count(nullif(rating3,0))+count(nullif(rating4,0))+count(nullif(rating5,0)))
as avg_rating,
count(*) as number_of_responses, employee
From CSEReduxResponses where month(approveddate)= 6 AND year(approveddate)=2014 group by employee ;
答案 2 :(得分:0)
我还想出了一个使用UDF的稍微光滑的版本。我更喜欢这个,因为平均函数可能对其他查询有用...
DELIMITER //
DROP FUNCTION IF EXISTS cca_wip.avg_ignore0//
CREATE FUNCTION cca_wip.avg_ignore0(
str VARCHAR(500)
) RETURNS double
COMMENT 'values separated by a coma, that are to be averaged. 0 will be treated as NULL'
BEGIN
DECLARE ss TEXT;
DECLARE sum, count double;
IF length(str)=0 or str not regexp '[0-9]' then RETURN 0;
end if;
IF str regexp '[a-z]' then RETURN NULL;
end if;
SET str=replace(str,'NULL','0');
SET sum =0;
SET count =0;
WHILE length(str)>0 DO
set ss=substring_index(str,',',1);
SET sum = sum + ss;
IF ss>0 THEN SET count = count+1;
END IF;
set str=trim(trim(trim(',') from trim(trim(ss from str))));
END WHILE;
RETURN (sum/count);
END//
DELIMITER ;
select
avg_ignore0(group_concat(concat_ws(',',rating1,rating2,rating3,rating4,rating5))),
count(*) as number_of_responses,
employee
From CSEReduxResponses
where
month(approveddate)= 6 AND year(approveddate)=2014
group by employee ;