按日期分组行
Group Rows by Date
有人要求我将发生在两分钟内的事务分组到单独的“日期组”中。我很难思考如何按分钟拆分数据。
我在下面写了一个测试 table 以及预期的“日期组”
CREATE TABLE #tmpData
(ID int,actionDt datetime)
INSERT INTO #tmpData
(ID,actionDt)
VALUES
(1, '7/22/2021 9:51'),
(1, '7/22/2021 9:52'),
(1, '7/22/2021 9:55'),
(1, '7/22/2021 9:56'),
(1, '7/22/2021 9:57'),
(1, '7/22/2021 9:58'),
(1, '7/22/2021 10:00'),
(1, '7/22/2021 10:10'),
(2, '7/22/2021 8:38'),
(2, '7/22/2021 8:39'),
(2, '7/22/2021 8:40'),
(2, '7/22/2021 12:05')
预期的“日期组”应该是
id
DtGroup
1
2021 年 7 月 22 日 9:51
1
2021 年 7 月 22 日 9:55
1
2021 年 7 月 22 日 9:58
1
2021 年 7 月 22 日 10:10
2
2021 年 7 月 22 日 8:38
2
2021 年 7 月 22 日 12:05
我写了下面接近的内容,但是 ID 1 的时间戳 9:58 和 10:00 应该是它们自己的日期组。
;with resultSet AS
(
SELECT a.id, a.actiondt, a.diff FROM
(
SELECT
id,
actiondt,
diff = datediff(mi,lag(actiondt) OVER (PARTITION BY id ORDER BY actiondt),actiondt)
FROM #tmpdata
) AS a
WHERE diff IS NULL OR diff > 2
)
SELECT
t.id,
t.actiondt AS currDt,
resultset.actiondt AS DtGrp
from #tmpdata t
left JOIN resultset
on t.id = resultset.id
and t.actiondt between dateadd(mi,-2,resultset.actiondt) and dateadd(mi,2,resultset.actiondt)
actionDt 之间的逻辑是否为 2 分钟或更长?如果是这样,预期结果应该如下吗?否则,我不明白你的预期结果试图帮助。
(1, '7/22/2021 9:51'),
(1, '7/22/2021 9:55'),
(1, '7/22/2021 9:57'),
(1, '7/22/2021 10:00'),
(1, '7/22/2021 10:10'),
(2, '7/22/2021 8:38'),
(2, '7/22/2021 8:40'),
(2, '7/22/2021 12:05')
这将为您提供上述结果。
declare @Count int,
@LoopCount int,
@PrevMinutes int,
@CurrentMinutes int,
@NextMinutes int,
@PrevFlag int,
@Flag int
;with dID as (
select distinct id,
actiondt
from #tmpData
)
select
identity(int,1,1) RowNo,
d.id as Grp,
d.actiondt,
lag(DATEPART(mi, d.actiondt), 1,0) over (order by d.actiondt) as PrevMinutes,
DATEPART(mi, d.actiondt) as CurrentMinutes,
lead(DATEPART(mi, d.actiondt), 1,0) over (order by d.actiondt) as NextMinutes,
0 as flag
into #Temp
from #tmpData d
full outer join dID on d.id = dID.id
and d.actiondt = dID.actiondt
order by d.id, actiondt
select @Count = @@RowCount
set @LoopCount = 1
while @LoopCount <= @Count
begin
set @PrevMinutes = (select PrevMinutes from #Temp where RowNo = @LoopCount)
set @CurrentMinutes = (select CurrentMinutes from #Temp where RowNo = @LoopCount)
set @NextMinutes = (select NextMinutes from #Temp where RowNo = @LoopCount)
set @Flag = (select flag from #Temp where RowNo = @LoopCount)
set @PrevFlag = (select flag from #Temp where RowNo = @LoopCount - 1)
if (@LoopCount = 1)
begin
update #Temp
set flag = 1
where RowNo = 1
end
else if (abs(@PrevMinutes - @CurrentMinutes) >= 2)
begin
update #Temp
set flag = 1
where RowNo = @LoopCount
end
else if (@PrevFlag = 0 and @Flag = 0)
begin
update #Temp
set flag = 1
where RowNo = @LoopCount
end
set @LoopCount=@LoopCount + 1
end
select Grp as id,
actiondt
from #Temp
where flag = 1
有人要求我将发生在两分钟内的事务分组到单独的“日期组”中。我很难思考如何按分钟拆分数据。
我在下面写了一个测试 table 以及预期的“日期组”
CREATE TABLE #tmpData
(ID int,actionDt datetime)
INSERT INTO #tmpData
(ID,actionDt)
VALUES
(1, '7/22/2021 9:51'),
(1, '7/22/2021 9:52'),
(1, '7/22/2021 9:55'),
(1, '7/22/2021 9:56'),
(1, '7/22/2021 9:57'),
(1, '7/22/2021 9:58'),
(1, '7/22/2021 10:00'),
(1, '7/22/2021 10:10'),
(2, '7/22/2021 8:38'),
(2, '7/22/2021 8:39'),
(2, '7/22/2021 8:40'),
(2, '7/22/2021 12:05')
预期的“日期组”应该是
id | DtGroup |
---|---|
1 | 2021 年 7 月 22 日 9:51 |
1 | 2021 年 7 月 22 日 9:55 |
1 | 2021 年 7 月 22 日 9:58 |
1 | 2021 年 7 月 22 日 10:10 |
2 | 2021 年 7 月 22 日 8:38 |
2 | 2021 年 7 月 22 日 12:05 |
我写了下面接近的内容,但是 ID 1 的时间戳 9:58 和 10:00 应该是它们自己的日期组。
;with resultSet AS
(
SELECT a.id, a.actiondt, a.diff FROM
(
SELECT
id,
actiondt,
diff = datediff(mi,lag(actiondt) OVER (PARTITION BY id ORDER BY actiondt),actiondt)
FROM #tmpdata
) AS a
WHERE diff IS NULL OR diff > 2
)
SELECT
t.id,
t.actiondt AS currDt,
resultset.actiondt AS DtGrp
from #tmpdata t
left JOIN resultset
on t.id = resultset.id
and t.actiondt between dateadd(mi,-2,resultset.actiondt) and dateadd(mi,2,resultset.actiondt)
actionDt 之间的逻辑是否为 2 分钟或更长?如果是这样,预期结果应该如下吗?否则,我不明白你的预期结果试图帮助。
(1, '7/22/2021 9:51'),
(1, '7/22/2021 9:55'),
(1, '7/22/2021 9:57'),
(1, '7/22/2021 10:00'),
(1, '7/22/2021 10:10'),
(2, '7/22/2021 8:38'),
(2, '7/22/2021 8:40'),
(2, '7/22/2021 12:05')
这将为您提供上述结果。
declare @Count int,
@LoopCount int,
@PrevMinutes int,
@CurrentMinutes int,
@NextMinutes int,
@PrevFlag int,
@Flag int
;with dID as (
select distinct id,
actiondt
from #tmpData
)
select
identity(int,1,1) RowNo,
d.id as Grp,
d.actiondt,
lag(DATEPART(mi, d.actiondt), 1,0) over (order by d.actiondt) as PrevMinutes,
DATEPART(mi, d.actiondt) as CurrentMinutes,
lead(DATEPART(mi, d.actiondt), 1,0) over (order by d.actiondt) as NextMinutes,
0 as flag
into #Temp
from #tmpData d
full outer join dID on d.id = dID.id
and d.actiondt = dID.actiondt
order by d.id, actiondt
select @Count = @@RowCount
set @LoopCount = 1
while @LoopCount <= @Count
begin
set @PrevMinutes = (select PrevMinutes from #Temp where RowNo = @LoopCount)
set @CurrentMinutes = (select CurrentMinutes from #Temp where RowNo = @LoopCount)
set @NextMinutes = (select NextMinutes from #Temp where RowNo = @LoopCount)
set @Flag = (select flag from #Temp where RowNo = @LoopCount)
set @PrevFlag = (select flag from #Temp where RowNo = @LoopCount - 1)
if (@LoopCount = 1)
begin
update #Temp
set flag = 1
where RowNo = 1
end
else if (abs(@PrevMinutes - @CurrentMinutes) >= 2)
begin
update #Temp
set flag = 1
where RowNo = @LoopCount
end
else if (@PrevFlag = 0 and @Flag = 0)
begin
update #Temp
set flag = 1
where RowNo = @LoopCount
end
set @LoopCount=@LoopCount + 1
end
select Grp as id,
actiondt
from #Temp
where flag = 1