当前位置: 首页 > 面试题库 >

T-SQL脚本-时间轴的逻辑问题

娄浩荡
2023-03-14
问题内容

创建了两个临时表,然后将它们加载…这是架构。

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)

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

一点背景-#SH标题表将人员时间表保存为“ Start_minute”,并以分钟为单位“
schedule_length”。例如,如果开始时间和计划时间均为480,则将其表示为8am(8am = 480th分钟),直到4pm(480分钟后,4pm
= 960th分钟)。

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

该查询有效:

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的计算值

这将返回类似:

   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行的开始时间对齐,因此应该合并起来,这样我的结果看起来像这样:

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上。

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


问题答案:

无需CTE,您所需要的只是一个辅助表格。一次创建它,如下所示:

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

然后,您只需要一点技巧即可:

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问题。不要问“哪些范围没有间隔”,请问“哪些分钟有间隔”。其余的都从那里开始。



 类似资料:
  • 问题内容: 好吧,我有一张看起来像这样的表 现在,我需要将其转换为: 我一直在看动态透视图示例,但是我似乎无法使其适合我的情况。 有人可以帮忙吗? 问题答案: 看下面的例子

  • 问题内容: 是否可以抑制由T-SQL脚本生成的警告?如果是这样,怎么办? 我知道我可以打开“受影响的记录”消息 但是有等同于警告的内容吗?例如: 如果我预计会出现这些错误,则可以从较大的脚本中筛选出糠cha中的实际错误。 谢谢。 问题答案: 请参见SET ANSI_WARNINGS {ON | 离开}

  • 问题内容: 我与第三方数据库,该数据库(无论何种原因)内部存储格式的日期的工作如用于作为。 有没有简单的方法可以将其转换为SQL Server类型? 我尝试将上面的内容手动转换为长度为6的字符序列,并将其与“ 01”连接起来以获取给定月份的开始,如下所示: 然后将其包装在转换中: 但这似乎抛出了; 从字符串转换日期和/或时间时转换失败 谁能告诉我我在做什么错? 谢谢!:) 问题答案: 您需要使用正

  • 所有链将组成一个二叉树,这就是它们的逻辑关系。 链ID为64位数字,从1开始,所以最多可以有2^64-1条链。 每条链可以有2条子链。 通过这种方式,链的数量和位置确定,方便扩展和跨链访问。

  • 问题内容: 给定开始日期和结束日期,我需要计算这两个日期之间的实例数。因此,给出以下内容: 桌子: 如果我在第一个(01/01)和第二个(02/01)之间看,我希望计数为2。如果我在寻找第3个到第4个,则期望计数为3。在整个日期范围内,那么我希望计数为4。有意义吗? 注意: 日期已转换为午夜,无需为此添加任何代码。此外,在整个问题中,日期均为dd / MM / yyyy格式。 目前,我有类似以下内

  • when: 条件判断语句,类似于变成语言中的if loop: 循环语句,类似于编程语言的中的while block: 把几个tasks组成一块代码,便于针对一组操作的异常处理等操作。