SQL Server 2005查询通过日期删除重复项

时间:2011-02-03 08:52:44

标签: 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      fname@isp.com       XYZ      2010-05-13 00:00:00.000
Fname2      Lname2      fname2@isp2.com     XYZ      2010-06-05 00:00:00.000
Fname2      Lname2      fname2@isp2.com     ASD      2008-09-17 12:01:45.407

正如您所看到的,Fname2显示两次,但只有BCodeBillDate存在差异。

如何使用最新日期进行此操作,以便我获得Fname2记录的XYZ的Bcode,日期为2010-06-05。

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

2 个答案:

答案 0 :(得分: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

这个带有ROW_NUMBER()子句的CTE将:

  • 将您的数据“分区”(FirstName,LastName) - 每对值都会获得一个新的顺序“行号”
  • 通过降序BillDate
  • 对每个分区中的值进行排序

因此,得到的数据集具有RowNum = 1的任何(FirstName,LastName)组的每个最新条目 - 这就是我从该CTE中选择的数据。

这对你有用吗?

答案 1 :(得分:1)

执行第二次连接(使用LEFT JOIN)在Bill表中查找后面的行,然后过滤该连接成功的所有结果:

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