2014-09-03 4 views
0

Я извлекаю данные из трех отдельных связанных с работником таблиц, все из которых объединены в SSN. Поскольку некоторые сотрудники несколько раз переходили в компанию, у них есть несколько дат аренды/разделения в системе, поэтому, когда я вытягиваю из этой таблицы даты найма, она дублирует строку по количеству дат аренды/разделения в системе. Вот выборка данных, как это вытащил:SQL Server 2012 - MAX() Функция

SSN   Name  Pay_Date Hire_Date 
123456789 John Doe 5/1/2012 1/1/2001 
123456789 John Doe 5/1/2012 2/5/2005 
123456789 John Doe 5/1/2012 3/1/2012 
123456789 John Doe 5/15/2012 1/1/2001 
123456789 John Doe 5/15/2012 2/5/2005 
123456789 John Doe 5/15/2012 3/1/2012 
123456789 John Doe 5/29/2012 1/1/2001 
123456789 John Doe 5/29/2012 2/5/2005 
123456789 John Doe 5/29/2012 3/1/2012 

Запрос:

SELECT 

SSN, Name, Pay_Date, Hire_Date 

FROM Personnel as PER 

LEFT JOIN Payroll as PAY on PER.SSN = PAY.SSN 

LEFT JOIN HumanResources as HR on PER.SSN = HR.SSN 

ORDER BY Pay_Date(DESC) 

Для устранения строки с датами аренды 1/1/2001 и 2/5/2005, я попытался с помощью функции MAX следующим образом, не повезло. Я попытался использовать множество примеров, опубликованных в предыдущих разделах, связанных с MAX, но ничего не работает.

SELECT 

SSN, Name, Pay_Date, MAX(Hire_Date) 

FROM Personnel as PER 

LEFT JOIN Payroll as PAY on PER.SSN = PAY.SSN 

LEFT JOIN HumanResources as HR on PER.SSN = HR.SSN 

GROUP BY SSN 

ORDER BY Pay_Date(DESC) 

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

SSN   Name  Pay_Date Hire_Date 
123456789 John Doe 5/1/2012 3/1/2012 
123456789 John Doe 5/15/2012 3/1/2012 
123456789 John Doe 5/29/2012 3/1/2012 
+0

Можете ли вы показать базовые таблицы для вашего примера? – Ndech

ответ

0

Это последняя дата оплаты и дата найма? если это так, то это должно сработать.

SELECT 

SSN, Name, MAX(Pay_Date), MAX(Hire_Date) 

FROM Personnel as PER 

LEFT JOIN Payroll as PAY on PER.SSN = PAY.SSN 

LEFT JOIN HumanResources as HR on PER.SSN = HR.SSN 

GROUP BY SSN, Name 

ORDER BY Pay_Date(DESC) 
+0

Это только последняя дата найма. – Joseph

0

Чтобы получить строку с последней датой аренды:

SELECT 
SSN, Name, Pay_Date, Hire_Date 
FROM Personnel as PER 
LEFT JOIN Payroll as PAY on PER.SSN = PAY.SSN 
LEFT JOIN HumanResources as HR on PER.SSN = HR.SSN 
WHERE ROW_NUMBER() OVER (PARTITION BY SSN, ORDER BY Hire_Date DESC)=1 
ORDER BY Pay_Date DESC 
+1

Вы не можете использовать ROW_NUMBER в предложении WHERE напрямую. –

+0

Действительно? Полезно знать ... подумал, что я мог бы сделать короткий отрезок от CTE таким образом. Я также не заметил, что OP использовал тот же SSN во всех строках своих выборочных данных, поэтому ваш раздел более прав, чем мой. Думаю, я скоро удалю этот ответ. –

2
;WITH MyCTE AS 
(
    SELECT SSN, 
        Name, 
        Pay_Date, 
        Hire_Date, 
        ROW_NUMBER() OVER(PARTITION BY SSN, Name, Pay_Date ORDER BY Hire_Date DESC) AS rn 
    FROM  Personnel as PER 
    LEFT JOIN Payroll as PAY on PER.SSN = PAY.SSN 
    LEFT JOIN HumanResources as HR on PER.SSN = HR.SSN 
) 
SELECT * 
FROM MyCTE 
WHERE rn = 1 

SQL Fiddle DemoРаботает на Lamak

+1

+1. У вас есть опечатка в вашем коде (вы написали 'ORDE BY', у него отсутствует' R'). И [здесь sqlffidle] (http://sqlfiddle.com/#!6/3a4a5/2) с демо-кодом вашего кода – Lamak

+0

Я отредактировал свой ответ. Я пишу с телефона, поэтому не мог использовать скрипку. Могу ли я использовать ваш образец с вашего разрешения? –

+0

Конечно, вот почему я разместил его здесь :-) – Lamak

0

агрегатные функции в данном случае являются проблематичными, поскольку MAX() данные для разные столбцы могут поступать из разных строк в вашем наборе.

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

SELECT SSN, Name, Pay_Date, Hire_Date 
FROM 
    (
    SELECT 

     SSN 
     , Name 
     , Pay_Date 
     , Hire_Date 
     , ROW_NUMBER() over (PARTITION BY SSN ORDER BY Hire_Date DESC) rn 
    FROM 
     Personnel as PER 

     LEFT JOIN Payroll as PAY on PER.SSN = PAY.SSN 

     LEFT JOIN HumanResources as HR on PER.SSN = HR.SSN 
    ) x 

WHERE 
    x.rn = 1 

ORDER BY Pay_Date DESC 
+0

он продолжает давать мне неправильный синтаксис рядом с «ГДЕ». Когда я нахожусь над ошибкой, он говорит, что ожидает AS, ID или QUOTED_ID. Но это не имеет смысла, и когда я их пробовал, они не работают в пути – Joseph

+0

Извините, несколько синтаксических ошибок. Я добавил псевдоним «x» и удалил круглые скобки (DESC). Фактически, использовал sqlfiddle от @Lamak для тестирования, и теперь это должно быть хорошо. – Greenspark