Не удается получить точные последние записи с двумя столбцами, имеющими одинаковое значение - в SQL Server - PullRequest
2 голосов
/ 07 июля 2019

Я пытаюсь получить отдельные записи для конкретного отдела из таблицы employee.

Я пытался с этим кодом в SQL Server, и я получаю эту ошибку:

Ошибка: employeeId недопустим в списке выбора, поскольку он не содержится ни в статистической функции, ни в предложении GROUP BY.

Мой код:

SELECT 
    name, department, MAX(jointime) LatestDate, employeeId
FROM 
    employee 
WHERE
    department = 'Mechanical'
GROUP BY 
    name 

Записи в БД:

name    department           joinTime            EmployeeId
-----------------------------------------------------------
Erik    Mechanical           2019-07-06 11:59:59    456
Tom     Mechanical           2019-07-06 11:59:59    789
Erik    Computer             2019-07-05 11:59:59    222
Erik    Computer             2019-07-04 11:59:59    111
Erik    Mechanical           2019-07-01 11:59:59    123

Я хочу получить результат при выполнении запроса для «Механического». Последняя запись должна быть получена из БД для определенного отдела.

name    department           joinTime            EmployeeId
-----------------------------------------------------------
Erik    Mechanical    2019-07-06 11:59:59     456
Tom     Mechanical    2019-07-06 11:59:59     789

Ответы [ 5 ]

3 голосов
/ 07 июля 2019

Предполагается, что ключом является [Имя], а не [EmployeeId]

Одним из вариантов является предложение WITH TIES, и, следовательно, нет необходимости в агрегировании

Пример

Select Top 1 with ties * 
 From  employee
 Where department='Mechanical'
 Order By Row_Number() over (Partition By [Name] order by joinTime Desc)

Возвращает

name    department  joinTime                 EmployeeId
Erik    Mechanical  2019-07-06 11:59:59.000  456
Tom     Mechanical  2019-07-06 11:59:59.000  789
1 голос
/ 07 июля 2019

Вы можете использовать ROW_NUMBER, чтобы отметить последнюю строку для каждого сотрудника, или CROSS APPLY, чтобы запустить коррелированный подзапрос для каждого сотрудника.

with q as
(
    SELECT name, department, jointime, employeeId, 
           row_number() over (partition by name, order by joinTime desc) rn
    FROM employee where  department='Mechanical'
)
select name, department, jointime, employeeId
from q
where rn = 1

или

with emp as
(
  select distinct name from employee
)
select e.*
from q
cross apply
(
  select top 1 * 
  from employee e2 
  where e2.name = q.name
  order by joinDate desc
) e
1 голос
/ 07 июля 2019

Вы можете использовать EXISTS:

SELECT e.*
FROM employee e
WHERE e.department='Mechanical'
AND NOT EXISTS (
  SELECT 1 FROM employee
  WHERE department = e.department
  AND name = e.name AND joinTime > e.joinTime
)

См. Демоверсию .Результаты:

> name | department | joinTime            | EmployeeId
> :--- | :--------- | :------------------ | ---------:
> Erik | Mechanical | 2019-07-06 11:59:59 |        456
> Tom  | Mechanical | 2019-07-06 11:59:59 |        789
0 голосов
/ 07 июля 2019

Просто добавьте отдел, employeeId в GROUP BY

SELECT name , department,   MAX(jointime) LatestDate , employeeId
FROM employee where  department='Mechanical'
GROUP BY name, department, employeeId
0 голосов
/ 07 июля 2019

Вам необходимо использовать функции AGGREGATE для полей, которые используются в операторе SELECT:

SELECT name, 
  MIN(department)
, MAX(jointime) LatestDate, 
, MIN(employeeId)
FROM employee where  department='Mechanical'
GROUP BY name

SQL-сервер находит все записи с именами Tom или Erik, но SQL Server не знаеткакое одно значение из нескольких строк следует выбрать для таких полей, как department или employeeId.Используя агрегированные функции, вы советуете SQL Server получить значения MIN, MAX, SUM, COUNT этих столбцов.

ИЛИ использовать эти столбцы в предложении GROUP BY, чтобы получитьвсе уникальные строки:

SELECT name 
    , department
    , jointime 
    , employeeId
    FROM employee where  department='Mechanical'
    GROUP BY  name
            , department
            , jointime 
            , employeeId
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...