2014-09-03 149 views
0

我從3個單獨的員工相關表中提取數據,所有表都加入了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和2005年2月5日的行,我嘗試使用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 2014-09-03 17:43:33

回答

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 2014-09-03 18:14:04

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

您不能直接在WHERE子句中使用ROW_NUMBER。 – 2014-09-03 17:48:30

+0

真的嗎?很高興知道......我認爲我可以通過CTE從捷徑中獲得捷徑。我也沒有注意到OP在其樣本數據的所有行上都使用了相同的SSN,所以您的分區比我的分區更加正確。我想我會很快刪除這個答案。 – 2014-09-03 17:53:44

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 2014-09-03 17:52:47

+0

我編輯了我的答案。我從我的手機寫信,所以不能真正使用小提琴。您可以在您的許可下使用您的樣品嗎? – 2014-09-03 17:54:48

+0

當然,這就是我在這裏發佈的原因:-) – Lamak 2014-09-03 17:55:15

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

它不斷給我'WHERE'附近不正確的語法。當我將鼠標懸停在錯誤上時,表示它期待AS,ID或QUOTED_ID。但是那些沒有意義,當我嘗試它們時,它們不起作用 – Joseph 2014-09-03 19:01:27

+0

對不起,有一些語法錯誤。我添加了別名'x'並從附近刪除了括號(DESC)。實際上使用@Lamak的sqlfiddle進行測試,現在應該很好。 – Greenspark 2014-09-03 21:22:54