创建两个临时表然后加载......这是模式。
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,那将是上午8点(上午8点=第480分钟),直到下午4点(480分钟后,下午4点=第960分钟)
#SD表包含标题的例外情况。在上面的例子中,该人可能会有一个午餐例外,即start_minute = 720和30(12:00 - 12:30)。
Date和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上加入表格。
进一步复杂化...上面的例子是需要组合的2行。我遇到了一个连续30分钟的记录,我需要将其记录到一个记录中。幸运的是它们不能重叠(你不会有2条记录占用相同的分钟数),但我认为我上面考虑的连接语句不会起作用。
答案 0 :(得分:2)
不需要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问题。不要问“哪个范围没有差距”,问“哪个分钟有间隔”。其余部分来自那里。
答案 1 :(得分:1)
如果使用递归CTE来组合上面的查询结果,则可以将最多32767条记录链接在一起。如果你不认为自己接近这个数量,你可能会考虑这种方法。
我创建了一个工作示例,因为我不确定。你的分组会有所不同,但这是一般的想法:
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