首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >T-SQL脚本-时间表的逻辑问题

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

Stack Overflow用户
提问于 2010-11-18 00:18:27
回答 2查看 747关注 0票数 5

创建了两个临时表,然后加载...这是模式。

代码语言:javascript
复制
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‘的persons时间表,并以分钟为单位表示'schedule_length’。例如,如果开始分钟和计划长度都为480,则读作8am (8am =480分钟),直到下午4点(480分钟后,4 4pm =960分钟)

#SD表保存标头的异常。在上面的例子中,这个人可能会有一个午餐例外,即start_minute = 720,长度为30 (12:00 - 12:30)。

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

下面的查询是有效的:

代码语言:javascript
复制
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的计算值

这将返回类似以下内容:

代码语言:javascript
复制
   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

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

代码语言:javascript
复制
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上。

上面的进一步complicate...the示例是需要组合的2行代码。我遇到了一个记录,它有30个1分钟的连续条目,我需要将它们写成一个单独的记录。幸运的是,它们不能重叠(您不会有两个记录占用相同的分钟),但我认为我上面考虑的join语句不适用于此。

EN

回答 2

Stack Overflow用户

回答已采纳

发布于 2010-11-18 01:47:53

不需要CTE,您只需要一个帮助表。只需创建一次,如下所示:

代码语言:javascript
复制
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

然后,你所需要的就是一点小技巧:

代码语言:javascript
复制
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问题可以通过重新组织它们来解决。不要问“哪些范围没有间隔”,而要问“哪些分钟有间隔”。其余的都是从那里开始的。

票数 2
EN

Stack Overflow用户

发布于 2010-11-18 00:33:34

如果您使用递归CTE来组合上面查询的结果,则可以将多达32767条记录链接在一起。如果你认为你永远不会达到这个数字,你可能会考虑这种方法。

我创建了一个工作示例,因为我不确定。您的分组可能会有所不同,但这是大体思路:

代码语言:javascript
复制
CREATE TABLE times
(
[Date] datetime,
[start] int,
[length] int,
[end] int
)
INSERT INTO times([Date], [Start], [length], [End])
VALUES ('11/11/2010',600,30,630)
INSERT INTO times([Date], [Start], [length], [End])
VALUES ('11/11/2010',630,40,670)
INSERT INTO times([Date], [Start], [length], [End])
VALUES ('11/11/2010',750,15,765)
INSERT INTO times([Date], [Start], [length], [End])
VALUES ('11/11/2010',800,40,840)

;WITH chaintimes AS
(
    SELECT t1.Date, t1.start, t1.length, t1.[end]
    FROM times t1 LEFT JOIN times t2 ON t1.start = t2.[end]
    WHERE t2.[end] IS NULL
    UNION ALL
    SELECT times.Date, chaintimes.start, chaintimes.length + times.length AS length, times.[end]
    FROM times INNER JOIN chaintimes ON times.start = chaintimes.[end]
)
, start_maxlength AS
(
    SELECT date, start, max(length) AS maxlength
    FROM chaintimes
    group by date, start
)
SELECT * FROM chaintimes ct
INNER JOIN start_maxlength ml
ON ct.Date = ml.Date AND ct.start = ml.start AND ct.length = ml.maxlength
票数 1
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/4206537

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档