T-SQL 脚本 - 时间线的逻辑问题 [英] T-SQL script - logic issues with timeline

查看:34
本文介绍了T-SQL 脚本 - 时间线的逻辑问题的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

创建并加载两个临时表...这是架构.

Two temp tables are created and then loaded...Here's the schema.

Create table #SH ([date] datetime,
        sched_id int,
        agent_id int)

Create table #SD (sched_id int,
        start_minute int,
        length int,
        exception_code int)

(不幸的是,架构和设计是我无法更改的,两个临时表都是从平面文件加载的.如果需要,我可以引入和加载新的临时表).

(Schema and design is something I can't change unfortunately, both temp tables are loaded from flat files. I can introduce and load new temp tables if needed).

一点背景 - #SH 标题表将人员日程表保存为Start_minute",并以分钟为单位显示schedule_length".例如,如果开始分钟和计划长度均为 480,则将读取为上午 8 点(上午 8 点 = 第 480 分钟)并持续到下午 4 点(480 分钟后,下午 4 点 = 第 960 分钟)

A little background - The #SH header table holds a persons schedule as 'Start_minute' and goes for 'schedule_length' in minutes. For example, if start minute and schedule length were both 480, that would read as 8am (8am = 480th minute) and goes until 4pm (480 minutes later, 4pm = 960th minute)

#SD 表包含标题的例外情况.在上面的示例中,此人可能会有一个午餐例外,即 start_minute = 720 和长度为 30 (12:00 - 12:30).

The #SD table holds exceptions to the header. In the example above, the person would likely have a lunch exception which would be start_minute = 720 and length of 30 (12:00 - 12:30).

日期和 agent_id 是我对#SH 唯一感兴趣的,#sd 中的异常信息是我感兴趣的.

Date and agent_id is the only thing I'm interested out of #SH, the exception info in #sd is what I'm interested in.

此查询有效:

Select [date],#sd.start_minute,#sd.length,#sd.start_minute + #sd.length as 'end_minute',agent_id
from #SH 
inner join #SD on #SD.sched_id = #sh.sched_id

*end_minute 最终是 start+length = end 的计算值

*end_minute is ultimately a calculated value of start+length = end

这将返回如下内容:

   Date     Start  length   end

1 2010-11-11 600    30  630

2 2010-11-11 630    40  670

3 2010-11-11 750    15  765

4 2010-11-11 800    40  840

现在我希望我可以说这已经结束并走开......但存在数据输入问题.在第 1 行和第 2 行中,第 1 行的结束时间与第 2 行的开始时间一致,应该合并,因此我的结果如下所示:

Now I wish I could say this was over and walk away...but data entry issues exist. In line 1 and 2, the end time of line 1 lines up with the start time in line 2 and should be combined so my results look like this :

Date     Start  length     end

1 2010-11-11 600    70  670

2 2010-11-11 750    15  765

3 2010-11-11 800    40  840

关于如何构建此逻辑以便我取回 3 行而不是 4 行的任何想法?我现在正在努力在 #sd1.start + #sd1.length = #sd2.start 上将表格加入自己.

Any idea's on how to build this logic so I get the 3 lines back instead of 4? I'm working on joining the table to itself on #sd1.start + #sd1.length = #sd2.start for now.

更复杂的是……上面的例子是需要合并的 2 行.我遇到了一个记录,它有 30 个连续的 1 分钟条目,我需要将其制作成单个记录.幸运的是,它们不能重叠(您不会有 2 条记录占用相同的分钟数),但我认为我上面考虑的 join 语句对此不起作用.

And to further complicate...the example above was 2 lines that needed combined. I've come across a record that had 30 1 minute entries in succession that I will need to make into a single record. Fortunately they cannot overlap (you won't have 2 records occupying the same minutes), but I don't think the join statement I'm considering above will work for that.

推荐答案

不需要 CTE,您只需要一个辅助表.创建一次,就像这样:

No need for a CTE, all you need is a helper table. Create it once, like so:

Create Table DayMinute(Minute Integer)
Declare @M Integer
Set @M = 1
While (@M <= 24*60)
Begin
  Insert Into DayMinute(Minute) Values(@M)
  Set @M = @M + 1
End

那么,你只需要一点技巧:

Then, all you need is a bit of tricksiness:

Select 
  DM.Minute,
  SD.Sched_ID
Into #MinutesWithException
From 
  DayMinute As DM
  Inner Join #SD As SD
    On DM.Minute Between SD.Start_Minute And SD.Start_Minute + Length

Select
  MWE.Sched_ID,
  SH.[Date],
  SH.Agent_ID,
  [Start_Minute] = MWE.Minute,
  [End_Minute] = (Select Min(Last.Minute) -- First one to have no successor
                  From #MinutesWithException As Last
                  Where Last.Sched_ID = MWE.Sched_ID
                    And Last.Minute > MWE.Minute
                    And Not Exists(Select *
                                   From #MinutesWithException As Next
                                   Where Next.Sched_ID = MWE.Sched_iD
                                     And Next.Minute = Last.Minute + 1))
From 
  #MinutesWithException As MWE
  Inner Join #SH As SH
    On MWE.Sched_ID = SH.Sched_ID
Where
  Not Exists(Select * -- All those without predecessor
             From #MinutesWithException As Previous
             Where Previous.Sched_ID = MWE.Sched_ID
               And Previous.Minute = MWE.Minute - 1)

请记住,许多 SQL 问题可以通过重新措辞来解决.不要问哪些范围没有间隙",而要问哪些分钟有间隔".其余的从那里开始.

Remember, a lot of SQL problems can be solved by rephrasing them. Don't ask "which ranges do not have a gap", ask "which minutes have an interval". The rest follows from there.

这篇关于T-SQL 脚本 - 时间线的逻辑问题的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆