Значение идентификатора теряется после выполнения MIN, а затем GROUP BY. Зачем? - PullRequest
0 голосов
/ 20 января 2010

Чтобы упростить, если бы у меня была таблица с именем 'employee':

id INT NOT NULL PRIMARY KEY,
salary FLOAT,
department VARCHAR(255)

Я хочу выполнить запрос и узнать, где я получаю минимальную зарплату в каждом отделе.Поэтому мой запрос выглядит примерно так:

SELECT employee.ID, MIN(employee.salary), employee.department
FROM employee
GROUP BY employee.department

Но независимо от того, какие записи найдены.Значения идентификатора в наборе результатов переименовываются в 1,2,3 .... до тех пор, пока в наборе результатов не будет много записей (отделов).

Как сохранить действительные идентификаторы сотрудников после выполнения функции AGGREGATE и GROUP BY?

Ответы [ 5 ]

4 голосов
/ 20 января 2010

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

Select EmployeeID
From Employee e
Where Salary = 
      (Select Min(Salary) From EMployee
       Where DepartmentId = e.DepartmentId)

, ноэто будет возвращать несколько записей на отдел, если более одного сотрудника имеют этот минимальный уровень заработной платы.

2 голосов
/ 20 января 2010

Полагаю, вы используете MySQL или SQLite, потому что ваш запрос неоднозначен и не разрешен стандартным SQL или большинством брендов СУБД.MySQL и SQLite более разрешительны, поэтому вы должны устранить неоднозначность.

Вот мое обычное исправление:

SELECT e1.ID, e1.salary, e1.department
FROM employee e1
LEFT OUTER JOIN employee e2 ON (e1.department = e2.department
    AND e1.salary > e2.salary)
WHERE e2.department IS NULL;

Вот еще одно решение, которое дает тот же результат:

SELECT e1.ID, e1.salary, e1.department
FROM employee e1
JOIN (SELECT e2.department, MIN(e2.salary) AS min_salary
      FROM employee e2 GROUP BY e2.department) d
  ON (e1.salary = d.min_salary);

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

1 голос
/ 20 января 2010

Ваш скрипт недействителен:

SELECT employee.ID, MIN(employee.salary), employee.department
FROM employee
GROUP BY employee.department

Вместо этого посмотрите на это:

SELECT MIN(employee.salary), employee.department
FROM employee
GROUP BY employee.department

Если вам также нужен идентификатор сотрудника, то вам нужно использовать подзапрос.

1 голос
/ 20 января 2010

Это поможет:

SELECT employee.department, MIN(employee.salary), employee.ID
FROM employee
GROUP BY 1
0 голосов
/ 20 января 2010

В современных выпусках SQL Server (и других достаточно мощных и современных механизмах SQL) «оконные функции» SQL, вероятно, являются лучшей альтернативой (предпочтительнее подзапросов и самостоятельных объединений) для выполнения того, что вы хотите:

  SELECT ID, salary, department
  FROM employee
  WHERE 1 = ROW_NUMBER() OVER(PARTITION BY department ORDER BY salary ASC)

Это работает, когда, если несколько сотрудников имеют одинаковую (минимальную по отделу) зарплату, вам нужен только один случайный выбор (вы можете добавить критерии к ORDER BY, если хотите, чтобы кто-то выбирал какой-то определенный критерии); посмотрите на RANK вместо ROW_NUMBER, если хотите все.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...