Oracle Предложение GROUP BY имеет проблему - PullRequest
2 голосов
/ 30 января 2020

SQL Запрос в базе данных oracle:

SELECT max(employee_id)
from bank_data
group by job_type
having job in ('Engineer','Artist');

Данные моей таблицы:

table data

I ошибка ниже:

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

В объяснении этого исключения говорится, что запрос не содержит всех выражений, но зачем мне включать дополнительные элементы, если я этого не хочу?

Ответы [ 3 ]

2 голосов
/ 05 февраля 2020

Это исключение возникает, когда в условии GROUP BY отсутствуют некоторые столбцы. В вашем случае вы пропустили один столбец.

Внутренняя работа & Root Причина:

Для выполнения этого запроса SQL Двигатель сначала вычисляет набор данных. Здесь присутствует только одна проекция (столбец), а именно. EMPLOYEE_ID. После получения этого начального набора данных механизм SQL далее пытается кластеризовать записи, т.е. группирует их на основе столбца job_type, чтобы выполнить условие GROUP BY в вашем запросе. В этот момент ваш запрос встречается с исключением, поскольку столбец job_type отсутствует в вашем наборе результатов.

Более того, ваше предложение GROUP BY ожидает только выбранные столбцы, и их порядок определяет их приоритеты при группировке, то есть упомянутый столбец будет получите наивысший приоритет, а последний последним будет иметь наименьшее значение.

Решение:

Измените ваш запрос следующим образом -

Select job_type, job, max(employee_id) from bank_data group by job_type, job having job in ('Engineer' , 'Artist');

Это исключит это исключение (Пожалуйста, измените порядок столбцов в предложении GROUP BY в соответствии с желаемыми приоритетами.

Конечно, вам нужно отфильтровать только соответствующие прогнозы (для этого полезны псевдонимы) в вашем конечном наборе результатов и для достижения этого вам нужно вложить этот запрос во внешний запрос.

Таким образом, ваш окончательный запрос будет выглядеть примерно так:

Select my_col from (select job_type, job, max(employee_id) as my_col from bank_data group by job_type, job having job in ('Engineer', 'Artist'));

Примечание:

Поскольку Oracle (включая другие, такие как MySQL, PostgreSQL, DB2 et c) подпадают под RDBMS (система управления реляционными базами данных) t это может быть не прямой запрос для получения нужных данных, поэтому вы должны проанализировать требования с помощью TR C (Tuple Relational Calculus), а затем вы можете создать соответствующий вложенный запрос на основе полученного выражения TR C. (Это очень полезно при создании сложных запросов).

1 голос
/ 30 января 2020

HAVING ведет себя как предложение where, которое выполняется после выполнения group by. Точно так же, как вы можете выбирать только столбцы / выражения, сгруппированные по ним, вы можете иметь ТОЛЬКО то, что появляется в группе, или является результатом агрегатной функции

По сути, ваш исходный запрос концептуально мог бы быть написан как это:

select * from
(
  select job_type, max(employee_id) as maxid 
  from bank_data
  group by job_type
) x
where job in ('Engineer','Artist') --job doesn't exist here

Это не совсем то же самое, что HAVING, но это поможет объяснить ключевую концепцию здесь: поскольку вы не группируете на работе, вы не можете использовать ее в HAVING (потому что подзапрос не выбирает задание, внешний запрос не может использовать его в WHERE).

Как указывает jarlh, вы, вероятно, просто хотите использовать предложение where. Я также рекомендую вам выбрать тип работы, потому что в противном случае вы получите две строки результатов и не будете знать, какой идентификатор сотрудника является максимальным для какого типа работы

select job_type, max(employee_id) as maxid 
from bank_data
where job in ('Engineer','Artist')
group by job_type;

Редактировать: после ваших комментариев:

select max(employee_id) as maxid 
from bank_data
where job in ('Engineer','Artist')
group by job;

Без использования группировки по / с размещением чисел в одной строке:

select max(a.employee_id) as maxengid, max(b.employee_id) as maxartistid 
from 
  (select * from bank_data where job in ('Engineer')) a 
  cross join bank_data b
  (select * from bank_data where job in ('Artist')) b

Или

select
  max(case when job = 'Engineer' then employee_id end) as maxengid,
  max(case when job = 'Artist' then employee_id end) as maxartgid 
from bank_data
where job in ('Engineer','Artist');
0 голосов
/ 30 января 2020

Если вы не хотите включать дополнительные вещи, то не включайте.

Если вы хотите, чтобы max (идентификатор сотрудника), используйте ниже:

    SELECT max(employee_id)
    from bank_data
    where job in ('Engineer','Artist');

Если вы хотите, чтобы ваш результат в соответствии с job_type. Затем используйте тип задания в столбцах выбора и используйте группирование по типу задания.

  SELECT max(employee_id) as eid,job_type from bank_data where job in ('Engineer','Artist')
    group by job_type;

См. Ниже URL:

'https://www.w3schools.com/sql/sql_groupby.asp'
'https://www.w3schools.com/sql/sql_having.asp'
'https://www.w3schools.com/sql/sql_min_max.asp'
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...