SQL-запрос для получения сотрудника, который не был оценен

#sql #oracle

Вопрос:

Существует таблица истории зарплат сотрудников sal_hist, в которой есть идентификатор,имя, зарплата и дата вступления в силу. Требование состоит в том, чтобы получить сотрудника, который не был оценен. Ниже приведена таблица:

ID Имя зарплата Дата
1 a 1000 10-5-2020
1 a 2000 12-6-2020
1 a 3000 12-7-2020
2 b 2500 12-5-2020
2 b 3500 12-7-2020
3 c 2500 12-5-2020

Ниже приведен запрос, который у меня есть:

 Select id,name from sal_hist group by id,name having count(1)=1;
 

Есть ли другой способ достичь результата?

Комментарии:

1. Какое отношение «оценено» имеет к этой таблице?

2. Что вы подразумеваете под другим способом? Что-то не так с тем, как у вас это уже есть?

Ответ №1:

Если в вашей date колонке указана дата оценки, и вам нужен пользователь, который не получил оценку на последнюю дату, то:

 SELECT id, name, salary, appraisal_date
FROM   (
  SELECT s.*,
         MAX(appraisal_date) OVER (PARTITION BY id) AS max_user_appraisal_date,
         MAX(appraisal_date) OVER () AS max_appraisal_date
  FROM   salary_history s
)
WHERE appraisal_date = max_user_appraisal_date
AND   max_user_appraisal_date < max_appraisal_date
 

Который, для выборочных данных:

 CREATE TABLE salary_history (Id, name, salary, appraisal_date) AS
SELECT 1, 'a', 1000, DATE '2020-05-10' FROM DUAL UNION ALL
SELECT 1, 'a', 2000, DATE '2020-06-12' FROM DUAL UNION ALL
SELECT 1, 'a', 3000, DATE '2020-07-12' FROM DUAL UNION ALL
SELECT 2, 'b', 2500, DATE '2020-05-12' FROM DUAL UNION ALL
SELECT 2, 'b', 3500, DATE '2020-07-12' FROM DUAL UNION ALL
SELECT 3, 'c', 2500, DATE '2020-05-12' FROM DUAL;
 

Выходы:

ID Имя зарплата ОЦЕНОЧНАЯ ДАТА
3 c 2500 12-20 МАЯ

бд<>скрипка <>здесь

Ответ №2:

Если вы ищете другой способ достижения результата и находите сотрудника, у которого указана только 1 зарплата (в прошлом никаких оценок), вы можете использовать подзапрос, подобный этому:

 SELECT id, name
FROM (
SELECT id, name, COUNT(id) AS [count]
FROM sal_hist 
GROUP BY id,name) 
WHERE count=1;
 

Но я бы отметил, что использование HAVING того, что у вас есть в настоящее время, является лучшим методом.