2014-09-03 165 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