2014-11-28 2 views
0

Мне нужно создать запрос T-SQL, который вернет самую высокую зарплату из таблицы job_positions и имя человека, у которого есть это.Выберите MAX() вызывает сообщение об ошибке

До сих пор мое решение:

SELECT 
    MAX(e.salary) AS [Max salary] 
    , p.firstname + ' ' + p.lastname AS [THE LUCKY MAN] 
FROM 
    persons p 
JOIN 
    job_positions e ON (p.id_person = e.id_person) 

Но это дает ошибку:

Msg 8120, Level 16, State 1, Line 67
Column 'persons.firstname' is invalid in the select list because it is not contained in either an aggregate function or the GROUP BY clause.

Msg 8120, Level 16, State 1, Line 67
Column 'persons.lastname' is invalid in the select list because it is not contained in either an aggregate function or the GROUP BY clause.

Однако, это только кажется, что само за себя; Вероятно, проблема связана с функцией MAX. После его удаления в результате получается таблица с полным именем и зарплатой. Интересно, почему он не может просто извлечь максимальный ряд ...

+2

ну, сообщение сообщает вам, что такое ошибка. Вы используете 'MAX', но у вас есть еще один столбец, который у вас нет на агрегатной функции, или вы используете его в' GROUP BY'. Добавьте 'GROUP BY p.firstname + '' + p.lastname' в конце вашего запроса – Lamak

+0

@Lamak То же самое, что и с ответом herbae:« Не работает - результат такой же, как если бы они не были «MAX», функции (полная таблица имен зарплат) ». – 0x6B6F77616C74

ответ

4

Если только один сотрудник, который может получить Max salary, тогда попробуйте это.

SELECT TOP 1 e.salary      AS [Max salary], 
      p.firstname + ' ' + p.lastname AS [THE LUCKY MAN] 
FROM persons p 
     JOIN job_positions e 
     ON (p.id_person = e.id_person) 
ORDER BY e.salary DESC 

Если более чем один получает максимальную зарплату затем использовать Window Function с Dense_Rank, чтобы найти все имена.

;WITH cte 
    AS (SELECT Dense_rank() 
        OVER (
        ORDER BY e.salary)   Rn, 
       e.salary      AS [Max salary], 
       p.firstname + ' ' + p.lastname AS [THE LUCKY MAN] 
     FROM persons p 
       JOIN job_positions e 
        ON (p.id_person = e.id_person)) 
SELECT * 
FROM cte 
WHERE Rn = 1 

ИЛИ

SELECT TOP 1 WITH TIES e.salary      AS [Max salary], 
      p.firstname + ' ' + p.lastname AS [THE LUCKY MAN] 
FROM persons p 
     JOIN job_positions e 
     ON (p.id_person = e.id_person) 
ORDER BY e.salary DESC 
+1

Вы также можете использовать ключевое слово 'with ties', если хотите дубликаты:' select top 1 with ties. , .'. –

+0

@ GordonLinoff - Спасибо, что Гордан узнал об этом. Обновленный ответ –

0

Попробуйте это:

SELECT MAX(e.salary) AS [Max salary], 
p.firstname+' '+p.lastname AS [THE LUCKY MAN] 
FROM persons p JOIN job_positions e ON (p.id_person = e.id_person) 
GROUP BY p.firstname, p.lastname -- group by clause needed 
+2

, в то время как это правильно, вы также должны объяснить, в чем проблема заключается в том, чтобы сделать это хорошим ответом. – pquest

+0

@pquest На самом деле это, вероятно, неверно, так как это даст максимальную зарплату на человека, где я подозреваю, что OP хочет в целом человек с самой большой зарплатой. – DavidG

+0

@ DavidG ах да, снова глядя, я думаю, что вы, вероятно, правы. При этом остальная часть моего комментария, которая была важной частью, все еще стоит. – pquest

0

Наконец нашел решение, которое не совсем некрасиво:

SELECT 
    MAX(e.salary) AS [Max salary] 
    , p.firstname + ' ' + p.lastname AS [THE LUCKY MAN] 
FROM 
    persons p 
JOIN 
    job_positions e ON (p.id_person=e.id_person) 
WHERE 
    e.salary=(SELECT max(e.salary) FROM e.job_positions) 

Но я до сих пор удивляюсь, почему ISN» t можно просто использовать «MAX» с выбором с «join».

Смежные вопросы