我有一个contactID和日期时间表,这是为联系人生成一封信的时间。每个联系人每天只能生成一个字母。我想编写一个查询来选择任何连续多天生成字母的联系人。
我想我需要在找到记录时增加日期时间,但我如何为每个联系人单独执行此操作?
答案 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)
我决定使用日历表。使用您最喜欢的搜索引擎查找用于创建日历表的脚本。
所以这是我已经完整推出的查询,之后我会解释它的详细信息
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的记录,即连续几天的联系人