ID DateTime EmailCount 93 6/1/2014 00:00:00 4 94 6/2/2014 00:00:00 4 95 6/3/2014 00:00:00 2 96 6/4/2014 00:00:00 2 97 6/5/2014 00:00:00 2 98 6/6/2014 00:00:00 2 99 6/7/2014 00:00:00 2 73 6/8/2014 00:00:00 2 74 6/9/2014 00:00:00 2 75 6/10/2014 00:00:00 4 76 6/11/2014 00:00:00 4 77 6/12/2014 00:00:00 2 78 6/13/2014 00:00:00 2 79 6/14/2014 00:00:00 2 80 6/16/2014 00:00:00 2 81 6/17/2014 00:00:00 4 82 6/18/2014 00:00:00 4 83 6/19/2014 00:00:00 4 84 6/20/2014 00:00:00 4 100 6/21/2014 00:00:00 4 101 6/22/2014 00:00:00 4 102 6/23/2014 00:00:00 4 103 6/24/2014 00:00:00 4 89 6/27/2014 00:00:00 4 90 6/28/2014 00:00:00 4 91 6/29/2014 00:00:00 4 92 6/30/2014 00:00:00 4 104 7/1/2014 00:00:00 4 105 7/2/2014 00:00:00 4 106 7/3/2014 00:00:00 4 121 7/6/2014 00:00:00 2 122 7/7/2014 00:00:00 2 123 7/8/2014 00:00:00 2
生成输出
Startdate EndDate EmailCount 6/3/2014 00:00:00 6/14/2014 00:00:00 2 6/16/2014 00:00:00 6/16/2014 00:00:00 2 7/6/2014 00:00:00 7/8/2014 00:00:00 2 6/1/2014 00:00:00 6/11/2014 00:00:00 4 6/17/2014 00:00:00 6/24/2014 00:00:00 4 6/27/2014 00:00:00 7/3/2014 00:00:00 4
这里,生成的输出并不完美,因为我想在以下组中使用StartDate到EndDate:(2014年6月3日到6/9/2014和EmailCount = 2)和(2014年6月10日到6月11日) 2014年和EmailCount = 4)和(2014年6月12日至2014年6月14日和EmailCount = 2)。此外,不应将数据库中的日期添加到组中。
答案 0 :(得分:0)
一个有点复杂的查询来解释,但这是一个尝试;
如果时间总是午夜,则可以使用公用表表达式为每行分配行号,并按日期和行号之间的差异进行分组。只要序列没有被破坏(即日期是连续的并且具有相同的emailid),它们将最终在同一组中,外部查询可以轻松地提取每个组的开始和结束日期;
WITH cte AS (
SELECT dateandtime, emailid,
ROW_NUMBER() OVER (PARTITION BY emailid ORDER BY dateandtime) rn
FROM mytable
)
SELECT MIN(dateandtime) start_time,
MAX(dateandtime) end_time,
MAX(emailid) emailid
FROM cte GROUP BY DATEADD(d, -rn, dateandtime) ORDER BY start_time
如果日期时间不总是午夜,则分组将失败。如果是这种情况,您可以添加一个公用表表达式,在运行此查询之前将日期时间转换为单独的步骤。
答案 1 :(得分:0)
您正在寻找具有相同EmailID的块中连续日期的运行。这假设您在日期中没有间隙。我不确定它是最优雅的方法,但你可以在这个主题上找到很多东西。
with BlockStart as (
select t.StartDate, t.EmailID
from T as t left outer join T as t2
on t2.StartDate = t1.StartDate - 1 and t2.EmailID = t1.EmailID
where t2.StartDate is null
union all
select max(StartDate) + 1, null
from T
) as BlockStart
select
StartDate,
(select min(StartDate) - 1 from BlockStart as bs2 where bs2 > bs.StartDate) as EndDate,
EmailID
from BlockStart as bs
where
EmailID is not null
-- /* or */ exists (select 1 from BlockStart as bs3 where bs3.StartDate > bs.StartDate)