连续一天查询

时间:2014-02-13 11:15:19

标签: sql-server sql-server-2005

我有一个contactID和日期时间表,这是为联系人生成一封信的时间。每个联系人每天只能生成一个字母。我想编写一个查询来选择任何连续多天生成字母的联系人。

我想我需要在找到记录时增加日期时间,但我如何为每个联系人单独执行此操作?

2 个答案:

答案 0 :(得分:1)

select contactid from ContactTable a inner join Contacttable B on a.contctid=b.contactid and datediff(day,a.date,b.date)=1

答案 1 :(得分:0)

我决定使用日历表。使用您最喜欢的搜索引擎查找用于创建日历表的脚本。

或者,here's one I made earlier

所以这是我已经完整推出的查询,之后我会解释它的详细信息

DECLARE @your_table table (
   contact_id int
 , created_on datetime
);

INSERT INTO @your_table (contact_id, created_on)
          SELECT 9, '2014-01-02 06:00'
UNION ALL SELECT 9, '2014-01-02 18:00'
UNION ALL SELECT 9, '2014-01-05 08:00'
UNION ALL SELECT 9, '2014-01-07 01:00'
UNION ALL SELECT 3, '2014-01-02 00:01'
UNION ALL SELECT 3, '2014-01-03 23:59' -- Over 24 hours but a "day" different
UNION ALL SELECT 7, '2014-01-04 01:00'
UNION ALL SELECT 7, '2014-01-06 01:00'
UNION ALL SELECT 7, '2014-01-08 01:00'
UNION ALL SELECT 7, '2014-01-09 01:00'
UNION ALL SELECT 7, '2014-01-10 01:00'
UNION ALL SELECT 7, '2014-01-11 01:00'
;

; WITH x AS (
  SELECT your_table.contact_id
       , your_table.created_on
       , calendar.the_date
       , Row_Number() OVER (PARTITION BY your_table.contact_id ORDER BY calendar.the_date) As sequence
  FROM   @your_table As your_table
   INNER
    JOIN dbo.calendar
      ON your_table.created_on >= calendar.the_date
     AND your_table.created_on <  DateAdd(dd, 1, calendar.the_date)
)
, y AS (
  SELECT curr.contact_id
       , curr.created_on
       , curr.the_date As the_date
       , prev.the_date As previous_date
       , DateDiff(dd, prev.the_date, curr.the_date) As difference_in_days
  FROM   x As curr
   LEFT
    JOIN x As prev
      ON curr.contact_id = prev.contact_id
     AND curr.sequence   = prev.sequence + 1
)
SELECT contact_id
     , created_on
     , the_date
     , previous_date
     , difference_in_days
FROM   y
WHERE  difference_in_days = 1

因为您没有提供我必须启动的任何示例数据,所以使用表变量(@your_table)作为其来源,查询是自包含的。

一旦填充,我们就开始使用几个Common-Table表达式(简称CTE)。如果您不熟悉这个概念,请在此处阅读:http://msdn.microsoft.com/en-us/library/ms175972.aspx。这些和子查询之间没有太大区别。

我们的第一个CTE(x)将@your_table加入calendar表。它通过返回created_on日期所在的日历中的单行来检查它是否大于(或等于)日历日期并且小于下一个日历日期(DateAdd() )。

完成后,我们使用窗口函数 - Row_Number()来提供一些排序。

我们为每个contact_id分区(即重置序列),并按created_on日期对序列进行排序。

继续进行第二次CTE(y):我们在CTE x上执行自我加入,根据排序将每个联系人记录与其“之前”联系起来。

这使我们可以计算出当前记录与之前记录之间的差异(DateDiff())。

最后,我们将结果集减少到只有天数差为1的记录,即连续几天的联系人