Группа SQL по функции (столбец) - теперь нельзя выбрать этот столбец

Я использовал схему сотрудников отдела кадров в Oracle Express и хотел выбрать сотрудников, нанятых в определенный год.

  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

Разве это невозможно?


person Mark Estrada    schedule 26.05.2011    source источник
comment
Является ли столбец найма_даты датой или типом символа? Вывод из: «описать сотрудников» расскажет вам об этом.   -  person richj    schedule 26.05.2011
comment
Почему вы используете substr() в столбце date? substr() для столбцов varchar. Если вам нужно получить части даты, вы должны вместо этого использовать to_char() (или извлечь). Вы полагаетесь на неявное преобразование данных, которое обязательно сломается при изменении настроек локали.   -  person a_horse_with_no_name    schedule 26.05.2011
comment
@a_horse_with_no_name Спасибо. Я впервые работаю с Oracle DB, но я включил это в свой список TODO. Ценю ваш вклад.. =)   -  person Mark Estrada    schedule 26.05.2011


Ответы (4)


Вы не можете выбрать полный 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), которые должны быть более надежными.

person paxdiablo    schedule 26.05.2011
comment
И вы также должны упомянуть, что делать SUBSTR на свидании - ОЧЕНЬ плохая идея (как уже упоминал a_horse_with_no_name). группировать по выдержке (год с даты найма) — это то, что нужно. - person Rob van Wijk; 26.05.2011
comment
@Rob, да, если предположить, что это это столбец даты. Это может быть char/varchar, что является другой проблемой :-) - person paxdiablo; 26.05.2011
comment
Это столбец даты. Это стандартная схема отдела кадров. - person Jeffrey Kemp; 27.05.2011

вы также можете обрезать столбец даты найма

select trunc(hiredate, 'yyyy'), count(*) 
from employee
group by trunc(hiredate, 'yyyy')
person schurik    schedule 26.05.2011

если вы хотите сгруппировать сотрудников по году их найма в использовании

select to_char(hiredate,'yyyy'),count(*) 
from employee
group by to_char(hiredate,'yyyy')
person josephj1989    schedule 26.05.2011

Вы можете использовать только GROUP BY условия или агрегатные функции (MIN, MAX, AVG и т. д.) в SELECT части GROUP BY запроса. Это работает:

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