2011-02-03 73 views
1

我搜索和搜索,似乎无法弄清这个问题: 我们有三个表中有我需要收集并显示在视图中的数据。SQL Server 2005查询通过日期删除重复

SELECT 
    C.FirstName, C.LastName, 
    aspnet_Membership.LoweredEmail, 
    MAX(Bill.Code) AS BCodes, 
    MAX(Bill.BillDate) 
FROM 
    dbo.Client C 
INNER JOIN 
    dbo.Bill ON C.Id = Bill.BId 
INNER JOIN 
    dbo.aspnet_Membership ON aspnet_Membership.UserId = C.UserGUID 
WHERE 
    ((Bill.Code='ASDF' 
    OR Bill.Code='XYZ' 
    OR Bill.Code='QWE' 
    OR Bill.Code='JKL') 
    AND C.LastName!='Unassigned') 
GROUP BY 
    LastName, FirstName, LoweredEmail, Code, BDate 

客户表有:FirstName LastName and UserGuid

比尔表有:BCode, BillDate

aspnet_Membership表有:E-mail, UserId

结果:

FirstName LastName E-mail    BCode BillDate 
FName1  Lname1  [email protected]  XYZ  2010-05-13 00:00:00.000 
Fname2  Lname2  [email protected]  XYZ  2010-06-05 00:00:00.000 
Fname2  Lname2  [email protected]  ASD  2008-09-17 12:01:45.407 

正如你可以看到Fname2小号升起两倍,唯一的区别是在BCodeBillDate

我怎样才能让这个去与最新的日期,所以我得到Fname2记录与XYZ的Bcode与日期2010-06-05。

任何帮助将不胜感激,谢谢你提前。

+0

你的groupby BCode让你有这种行为。不知何故,如果你可以从你的groupby中删除代码,它应该没问题。 – 2011-02-03 09:13:12

+0

而且BDate也是。基本上,如果你正在聚合一个列(使用MAX,SUM等),不要把它放在GROUP BY中,反之亦然。 – 2011-02-03 10:34:26

回答

1

执行第二个连接(使用LEFT JOIN)找到比尔表以后的行,然后过滤那个地方成功加入任何结果:

SELECT 
C.FirstName, C.LastName, 
aspnet_Membership.LoweredEmail, 
MAX(Bill.Code) AS BCodes, 
MAX(Bill.BillDate) 

FROM dbo.Client C 

INNER JOIN dbo.Bill 
ON C.Id=Bill.BId 

INNER JOIN dbo.aspnet_Membership 
ON aspnet_Membership.UserId=C.UserGUID 

LEFT JOIN dbo.Bill b2 
ON Bill.BId = b2.BId and 
    b2.Code in ('ASDF','XYZ','QWE','JKL') and 
    b2.BDate > Bill.BDate 

WHERE 
b2.BId is null and 
((Bill.Code='ASDF' 
OR Bill.Code='XYZ' 
OR Bill.Code='QWE' 
OR Bill.Code='JKL') 
AND C.LastName!='Unassigned') 
GROUP BY LastName, FirstName, LoweredEmail, Code, BDate 
+0

谢谢你完美的作品:)。 – AhsenB 2011-02-05 20:06:33

2

看到你正在使用SQL Server 2005,我可能会使用一个CTE(公共表表达式)来做到这一点 - 是这样的:

;WITH MyData AS 
(
    SELECT 
     c.FirstName, c.LastName, 
     asp.LoweredEmail, 
     b.Code AS BCodes, b.BillDate, 
     ROW_NUMBER() OVER (PARTITION BY c.LastName,c.FirstName 
          ORDER BY BillDate DESC) AS 'RowNum' 
FROM 
    dbo.Client c 
INNER JOIN 
    dbo.Bill b ON C.Id = b.BId 
INNER JOIN 
    dbo.aspnet_Membership asp ON asp.UserId = c.UserGUID 
WHERE 
    b.Code IN ('ASDF', 'JKL', 'QWE', 'XYZ') 
    AND c.LastName != 'Unassigned' 
) 
SELECT 
    FirstName, LastName, LoweredEmail, BCodes, BillDate 
FROM 
    MyData 
WHERE 
    RowNum = 1 

这CTE与ROW_NUMBER()子句:

  • “分区”您的数据由(FirstName,LastName) - 每对这些值的获取新的连续的“行号”
  • 为了每个分区中那些值由下降BillDate

因此而导致的数据集有对于任何(姓名,姓氏)组的每个最新条目与RowNum = 1 - 这就是我从该CTE中选择的数据。

这是否适合你?