【问题标题】:Merge/Combine continuous date records using loop in SQL在 SQL 中使用循环合并/组合连续日期记录
【发布时间】:2017-03-12 08:02:37
【问题描述】:

我有一个要求,我需要合并连续的并且属于某种类型的组和少数其他条件的记录。

  1. 列表项

要合并记录——我们应该认为它只有从主组开始才连续,所以这里的第一个记录应该被视为个体,即使它是连续的

  1. 列表项

如果不作为主组结束,则不要合并,

  1. 列表项

如果有一天的差距,那就不要合并

MemberName   Group  StartDate      EndDAte
Priya         Sub   01/01/2017     01/20/2017 --Do not merge,not started in Main
Priya         Main  01/20/2017     01/30/2017 --merge
Priya         Sub   01/30/2017     02/05/2017 --merge
Priya         Main  02/06/2017     02/06/2017 --Do not merge,Break
Priya         sub   02/07/2017     02/15/2017 --Do not merge,not started in Main
Priya         Main  02/15/2017     02/20/2017 --Merge
Priya         Main  02/20/2017     02/25/2017 --Do not merge,Break
Priya         sub   02/28/2017     02/28/2017 --Do not merge,break also did not end as Main

输出应如下所示:

MemberName   Group  StartDate      EndDAte
Priya        Sub    01/01/2017     01/20/2017 
Priya        Main   01/20/2017     02/05/2017
Priya        Main   02/06/2017     02/06/2017
Priya        sub    02/07/2017     02/15/2017
Priya        Main   02/15/2017     02/25/2017
Priya        sub    02/28/2017     02/28/2017 

我必须在这里使用 If-while 循环。

【问题讨论】:

  • 那么你的问题是什么?到目前为止你做了什么?使用 while 循环,这样做应该很简单。您也可以使用窗口函数,但这会复杂得多。
  • 我想我理解您所说的“如果它不以主要组结尾,则不要合并”的意思,但您能否通过其他示例说明此标准?。
  • @james Z,我使用了临时表并导出了输出,但感觉巨大且效率低下,我想使用循环,但我对 SQL 中的循环概念很陌生,请你帮我写循环
  • @SqlZim 我的意思是如果最后有差距我的意思是我们不应该加入它。

标签: sql sql-server tsql merge gaps-and-islands


【解决方案1】:

这不是使用循环来完成的,而是想测试如何使用窗口函数来完成。结果相当丑陋。很可能它也可以更轻松地完成,但是如果您开始从内到外研究它是如何工作的,您可能会学到一些技巧:

select * 
from (
    select *, row_number() over (partition by MemberName, GapTotal, MainGrp order by StartDate) as RN,
    first_value(EndDate) over (partition by MemberName, GapTotal, MainGrp order by StartDate desc) as LastEndDate
    from (
       select * , sum(Main) over (partition by MemberName order by StartDate) as MainGrp
       from (
            select *, case when [Group] = 'Main' and row_number() over (partition by MemberName, GapTotal, [Group] order by StartDate) = 1 then 1 else 0 end as Main
            from (
                select *, sum(Gap) over (partition by MemberName order by StartDate) as GapTotal
                from (
                    select 
                      *, 
                      isnull(datediff(day, lag(EndDate) over (order by StartDate), StartDate),0) as Gap 
                    from #tmp
                ) V
            ) W
        ) X
    ) Y
) Z
where RN = 1
order by MemberName, StartDate

这主要使用运行总计的技巧,使用它创建分组,然后用于确定是否可以合并行。

Example

【讨论】:

  • 嗨詹姆斯,感谢您的帮助,但要求更改为 loof for gap 7 天,即如果成员有不同的开始和结束日期并且他们之间的日期差异是
  • 没有点赞,也没有标记为答案,然后你问差不多一个月后如何将其更改为您的新要求?
  • 但是不管怎样,这个处理了这个差距,所以根据你的需要改变它datediff(day, lag(EndDate) over (order by StartDate), StartDate)
  • 嗨 james,我是 stack overfolw 的新手,所以我不知道投票的概念,但我非常感谢你的回答,我现在会标记它。
  • 如果您添加了一个案例,当它小于您的要求时使间隙为 0,那么它应该可以工作,我的意思是这部分:datediff(day, lag(EndDate) over (order by StartDate), StartDate)
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2013-03-24
  • 2012-04-16
  • 1970-01-01
相关资源
最近更新 更多