T-SQL在30天内查找具有联系日期的帐户

时间:2013-10-30 23:18:20

标签: sql sql-server-2008-r2

我有一个具有以下结构的表:

    Account_No   Contact Date
    -------------------------
    1            2013-10-1
    2            2013-9-12
    3            2013-10-15
    3            2013-8-1
    3            2013-8-20
    2            2013-10-25
    4            2013-9-12
    4            2013-10-2

我需要搜索该表并返回任何两个联系日期在30天之内的帐号。某些帐号可能有5或6个联系日期。我基本上只需要返回所有完整的帐号和彼此在30天内的记录,而忽略其余的。联系日期存储为日期数据类型。

因此,例如,帐号3将返回2013-8-1和2013-8-20记录,并且帐号4的两个记录也会出现,但不会显示其他帐号记录或帐户2013-10-15排名第3。

我使用的是SQL Server 2008 R2。

提前感谢您的帮助!

3 个答案:

答案 0 :(得分:2)

您可以在+/- 30天内使用DATEADD并与时间窗口进行比较:

DECLARE @ContactDates TABLE (
        Account_No  int
    ,   Contact     Date
)

-- Sample data
INSERT @ContactDates (Account_No, Contact)
VALUES
        (1,            '2013-10-01')
    ,   (2,            '2013-09-12')
    ,   (3,            '2013-10-15')
    ,   (3,            '2013-08-01')
    ,   (3,            '2013-08-20')
    ,   (2,            '2013-10-25')
    ,   (4,            '2013-09-12')
    ,   (4,            '2013-10-02')

-- Find the records within +/-30 days
SELECT  c1.Account_No, c1.Contact AS Contact_Date1
FROM    @ContactDates AS c1
   JOIN (
        -- Inner query with the time window
        SELECT  Account_No
            ,   Contact
            ,   DATEADD(dd, 30, Contact) AS Date_Max
            ,   DATEADD(dd, -30, Contact) AS Date_Min
        FROM    @ContactDates
    ) AS c2
        -- Compare based on account number, exclude the same date
        -- from comparing against itself. Usually this would be
        -- a primary key, but this example doesn't show a PK.
        ON (c1.Account_No = c2.Account_No AND c1.Contact != c2.Contact)
-- Compare against the +/-30 day window
WHERE   c1.Contact BETWEEN c2.Date_Min AND c2.Date_Max

返回以下内容:

Account_No Contact
========== ==========
3          2013-08-20
3          2013-08-01
4          2013-10-02
4          2013-09-12

答案 1 :(得分:1)

在SQL Server 2012中,您将拥有lag()lead()函数。在2008年,您可以对同一日历月中的值执行以下操作:

select distinct account_no
from t t1
where exists (select 1
              from t t2
              where t1.account_no = t2.account_no and
                    datediff(month, t1.ContactDate, t2.ContactDate) = 0
             )

在定义日期在不同月份的“月份”时,存在一些挑战。 (2月15日之后,3月16日是“一个月”吗?他们的时间比1月1日和1月31日更近。)你可以选择30天:

select distinct account_no
from t t1
where exists (select 1
              from t t2
              where t1.account_no = t2.account_no and
                    datediff(day, t1.ContactDate, t2.ContactDate) <= 30
             )

答案 2 :(得分:0)

每条记录都有一个ID吗?如果是这样你就不需要像我一样创建一个但基于你发布的数据

With cte as
(
    Select *, 
        row_number() over (order by contact_date) id
    From tbl
)

Select *
From cte b
Where exists (
    Select 1
    From cte a
    Where a.account_no = b.account_no
    And a.id <> b.id
    And a.contact_date between b.contact_date and dateadd(d, 30, b.contact_date)
 )
相关问题