栏目分类:
子分类:
返回
名师互学网用户登录
快速导航关闭
当前搜索
当前分类
子分类
实用工具
热门搜索
名师互学网 > IT > 面试经验 > 面试问答

多个日期范围之间的分钟总和

面试问答 更新时间: 发布时间: IT归档 最新发布 模块sitemap 名妆网 法律咨询 聚返吧 英语巴士网 伯小乐 网商动力

多个日期范围之间的分钟总和

Gordon Linoff有基于CTE的答案

我已经对所有可用算法进行了性能分析。空白值表示此过程花费了太长时间。这是在单个Core
i7 X920 @ 2GHz芯片上测试的,并带有几个SSD。创建的唯一索引是UserID
AvailStart上的群集。如果您认为可以改善任何性能,请告诉我。

此CTE版本比线性版本差,SQL Server无法以有效的方式执行RN = RN +
1联接。我在下面的一种混合方法中对此进行了纠正,在该方法中,我将第一个CTE保存并索引到表变量中。这仍然需要比基于游标的方法多十倍的IO。

With OrderedRanges as (  Select    Row_Number() Over (Partition By UserID Order By AvailStart) AS RN,    AvailStart,    AvailEnd  From    dbo.Available  Where    UserID = 456),AccumulateMinutes (RN, Accum, CurStart, CurEnd) as (  Select    RN, 0, AvailStart, AvailEnd  From    OrderedRanges  Where     RN = 1  Union All  Select    o.RN,     a.Accum + Case When o.AvailStart <= a.CurEnd Then        0      Else         DateDiff(Minute, a.CurStart, a.CurEnd)      End,    Case When o.AvailStart <= a.CurEnd Then         a.CurStart      Else        o.AvailStart      End,    Case When o.AvailStart <= a.CurEnd Then        Case When a.CurEnd > o.AvailEnd Then a.CurEnd Else o.AvailEnd End      Else        o.AvailEnd      End  From    AccumulateMinutes a        Inner Join     OrderedRanges o On         a.RN = o.RN - 1)Select Max(Accum + datediff(Minute, CurStart, CurEnd)) From AccumulateMinutes

http://sqlfiddle.com/#!6/ac021/2

经过性能分析后,这里是混合CTE /表变量版本,其性能比除基于游标的方法外要好

Create Function dbo.AvailMinutesHybrid(@UserID int) Returns Int AsBeginDeclare @UserRanges Table (  RN int not null primary key,   AvailStart datetime,   AvailEnd datetime)Declare @Ret int = Null;With OrderedRanges as (  Select    Row_Number() Over (Partition By UserID Order By AvailStart) AS RN,    AvailStart,    AvailEnd  From    dbo.Available  Where    UserID = @UserID)Insert Into @UserRanges Select * From OrderedRanges;With AccumulateMinutes (RN,Accum, CurStart, CurEnd) as (  Select    RN, 0, AvailStart, AvailEnd  From    @UserRanges  Where     RN = 1  Union All  Select    o.RN,     a.Accum + Case When o.AvailStart <= a.CurEnd Then        0      Else         DateDiff(Minute, a.CurStart, a.CurEnd)      End,    Case When o.AvailStart <= a.CurEnd Then         a.CurStart      Else        o.AvailStart      End,    Case When o.AvailStart <= a.CurEnd Then        Case When a.CurEnd > o.AvailEnd Then a.CurEnd Else o.AvailEnd End      Else        o.AvailEnd      End  From    AccumulateMinutes a        Inner Join     @UserRanges o On         a.RN + 1 = o.RN)Select   @Ret = Max(Accum + datediff(Minute, CurStart, CurEnd)) From   AccumulateMinutes Option  (MaxRecursion 0)Return @RetEnd

http://sqlfiddle.com/#!6/bfd94



转载请注明:文章转载自 www.mshxw.com
本文地址:https://www.mshxw.com/it/410909.html
我们一直用心在做
关于我们 文章归档 网站地图 联系我们

版权所有 (c)2021-2022 MSHXW.COM

ICP备案号:晋ICP备2021003244-6号