【问题标题】:Group Rows by Date按日期分组行
【发布时间】:2021-09-30 03:13:18
【问题描述】:

我被要求将在两分钟内发生的交易分成不同的“日期组”。我很难思考如何按分钟拆分数据。

我在下面写了一个测试表以及预期的“日期组”

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 7/22/2021 9:51
1 7/22/2021 9:55
1 7/22/2021 9:58
1 7/22/2021 10:10
2 7/22/2021 8:38
2 7/22/2021 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)

【问题讨论】:

  • 所以你只想要每组的起始行?为什么包含7/22/2021 9:58,上一行是7/22/2021 9:57
  • @Charlieface 9:58 距离上一个 9:55 发生的日期组超过两分钟。用户希望将操作分组为两分钟间隔:(

标签: tsql sql-server-2016


【解决方案1】:

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

【讨论】:

  • 你是对的。我误解了我的预期结果集。逻辑实际上是两分钟或更长时间。我会按照你的结果运行。感谢您的帮助!
猜你喜欢
  • 2019-02-19
  • 2011-02-19
  • 1970-01-01
  • 2023-02-07
  • 1970-01-01
  • 2015-06-26
  • 2021-06-05
  • 2012-05-28
  • 2011-12-30
相关资源
最近更新 更多