SQL Group By函数(列) - 现在无法选择该列

7

我在Oracle Express中使用了HR员工模式,并希望选择特定年份入职的员工。

  SELECT hire_date, 
         COUNT(*)
    FROM employees empl
GROUP BY SUBSTR(hire_date, -4)
ORDER BY empl.hire_date;

招聘日期列的格式为“1/1/2011”,我想通过提取最后四个字符来对它们进行分组。

问题是,我遇到了以下错误:

ORA-00979: not a GROUP BY expression
00979. 00000 -  "not a GROUP BY expression"
*Cause:    
*Action:
Error at Line: 1 Column: 7

这可行吗?

“hire_date”列是日期类型还是字符类型?从“describe employees”的输出中可以得知。 - richj
2
为什么在“date”列上使用substr()substr()是用于varchar列的。如果您需要获取日期的部分,应改用to_char()(或extract)。您正在依赖隐式数据转换,如果区域设置更改,则必定会出现错误。 - user330315
1
@a_horse_with_no_name 谢谢。这是我第一次使用Oracle数据库,但我已经将其放在我的TODO列表中。感谢您的建议.. =) - Mark Estrada
4个回答

9

如果你只按其后四位进行分组,那么无法选择完整的 hire_date。想象一下如果有两行:

hire_date
=========
01/01/2001
02/02/2001

当你对它们进行分组时,生成的单行中,hire_date 应该是什么呢?

所选的每一列必须是分组列或聚合列。换句话说,请尝试:

select substr(hire_date,-4), count(*)
from employees
group by substr(hire_date,-4)
order by empl.hire_date;

需要注意的是,逐行函数在扩展方面往往效果不佳。如果您想要经常处理年份,建议将其拆分成单独的列。这可能会大大提高性能,但是请量力而行,不要瞎猜!

正如其他人在评论中提到的那样,substr 可能不是最好的解决方案,因为它可能依赖于区域设置(例如:日期可能被格式化为 YYYY-MM-DD,这与 substring 不兼容)。

更好的方法可能是使用类似于 to_char(hire_date,'YYYY')extract (year from hire_date) 这样更加健壮的方法。


4
你还应该提到,在日期上执行SUBSTR是一个非常糟糕的想法(如a_horse_with_no_name所提到的)。 "group by extract(year from hire_date)"才是正确的方法。 - Rob van Wijk
@Rob,是的,假设它是一个日期列。它可能是char/varchar,这是一个不同的问题 :-) - paxdiablo
1
这是一个日期列。这是标准的 HR 模式。 - Jeffrey Kemp

7

您还可以截断 hiredate 列。

select trunc(hiredate, 'yyyy'), count(*) 
from employee
group by trunc(hiredate, 'yyyy')

1
如果你想按照员工入职年份对他们进行分组,请使用:
select to_char(hiredate,'yyyy'),count(*) 
from employee
group by to_char(hiredate,'yyyy')

0

GROUP BY 查询中,你只能在 SELECT 部分使用 GROUP BY 条件或聚合函数(MIN, MAX, AVG 等)。以下是有效的:

select substr(hire_date,-4), count(*)
from employees empl
group by substr(hire_date,-4)
order by substr(hire_date,-4);

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接