POSTGRESQL必须出现在GROUP BY中

时间:2018-12-15 18:03:13

标签: sql postgresql group-by case

我想选择一个案例,但收到以下错误消息:

ERROR:  column "employee_view.firstname" must appear in the GROUP BY clause 
or be used in an aggregate function

employee_view表中的样本数据:

 e_id  | firstname | lastname  | christmas_bonus 
-------+-----------+-----------+-----------------
 10100 | Mark      | Stevens   |       7500.0000
 10101 | Alex      | Watts     |       8700.0000
 10102 | Hannah    | Burton    |       7800.0000

我的查询:

select distinct e_id, firstname, lastname, christmas_bonus, case 
when christmas_bonus < round(avg(christmas_bonus),2) then 'bonus below average' 
else 'bonus above average' end from employee_view group by e_id;

所需的输出:

e_id  | firstname | lastname  | christmas_bonus | case 
------+-----------+-----------+-----------------+------
10100 | Mark      | Stevens   |       7500.0000 | bonus below average

2 个答案:

答案 0 :(得分:2)

您可以跳过GROUP BY部分,而改为使用窗口化的AVG

select e_id, firstname, lastname, christmas_bonus,
   case when christmas_bonus < round((avg(christmas_bonus) OVER()),2) 
        then 'bonus below average' else 'bonus equal or above average' end 
from employee_view 

答案 1 :(得分:0)

对于employee_view的每一行,您都希望将圣诞节奖金与所有雇员的平均值进行比较。

一个简单,高效且可能更易于维护的解决方案是计算查询中的总体平均值,然后将该值与每个员工奖金(Cross JOIN与employee表)进行比较。

因此,平均值仅计算一次,仅返回一行数据,因此您无需使用窗口函数或group by子句。

select 
    e.e_id, 
    e.firstname,
    e.lastname, 
    e.christmas_bonus, 
    case 
        when e.christmas_bonus < a.christmas_bonus then 'bonus below average'
        else 'bonus above average' 
    end 
from 
    employee_view e
    cross join (select avg(christmas_bonus) from employee_view) a
;