合并未使用的时隙(Merging unused timeslots)

2019-10-17 04:15发布

我有一个查询结果一样

|----------------------------------------------|
|StaffId|BranchId|StartTime|EndTime |PatientId |
|----------------------------------------------|
|1      |1       |09:30:00 |09:35:00|Null      |
|1      |1       |09:35:00 |09:40:00|Null      |
|1      |1       |09:40:00 |09:55:00|1         |
|1      |1       |09:55:00 |10:00:00|Null      |
|1      |1       |10:00:00 |10:05:00|Null      |
|1      |1       |10:05:00 |10:20:00|2         |
|1      |1       |10:20:00 |10:25:00|NULL      |
|1      |1       |10:25:00 |10:40:00|3         |
|1      |1       |10:40:00 |10:45:00|Null      |
|1      |1       |10:45:00 |10:50:00|Null      |
|1      |1       |10:50:00 |10:55:00|Null      |
|1      |1       |10:55:00 |11:00:00|Null      |
|----------------------------------------------|

但我希望能够把所有未使用的时隙(那些没有患者ID),所以结果是

|----------------------------------------------|
|StaffId|BranchId|StartTime|EndTime |PatientId |
|----------------------------------------------|
|1      |1       |09:30:00 |09:40:00|Null      |
|1      |1       |09:40:00 |09:55:00|1         |
|1      |1       |09:55:00 |10:05:00|Null      |
|1      |1       |10:05:00 |10:20:00|2         |
|1      |1       |10:20:00 |10:25:00|NULL      |
|1      |1       |10:25:00 |10:40:00|3         |
|1      |1       |10:40:00 |11:00:00|Null      |
|----------------------------------------------|

真的不知道如何去这样做,虽然,任何指导,将不胜感激。 不知道这是容易,但查询的结果通过只是使用SQL患者的5个分钟为间隔加入一个表有

INSERT INTO @Results(BranchId, StaffId, StartTime, EndTime)
SELECT us.BranchId, us.StaffId, us.StartTime, us.EndTime
FROM @UnusedSlots us
    left join @Results r
        on (NOT ((r.StartTime >= us.EndTime)
            OR (r.EndTime <= us.StartTime))) AND
            (us.StaffId = r.StaffId)
    where r.BranchId is Null

其中@UnusedSlots是可用5分钟槽和@Results包含预约时隙(与患者ID)。 如果没有建立合并为这条语句这将是更好的方式。

我以为我可以使用Min(StartTime)Max(EndTime) ,如果我能隔离没有PatientId毗邻的结果,但我不知道该怎么做,我一直有一个已经从09合并结束了: 30至11:00

Answer 1:

select 
    StaffId,
    BranchId,
    MIN(StartTime),
    MAX(EndTime),
    PatientId
from
(
select *,       
    ROW_NUMBER() over (order by starttime) 
      - ROW_NUMBER() over (partition by isnull(PatientID,-1) order by starttime) rn     
from @results
) v
group by staffid, branchid, patientid, rn
order by MIN (starttime)

我不知道,如果和STAFFID可以BranchID在@Results表有所不同,所以你可以,如果他们能需要调整这个。



Answer 2:

你可以使用光标,性能不会规模太好,但:

    create table #tempTimes (
        staffid int,
        branchid int,
        startTime datetime,
        endTime datetime,
        patientid int)

    insert into #temptimes values (1,1,'2012-09-09 09:30', '2012-09-09 09:35', null)
    insert into #temptimes values (1,1,'2012-09-09 09:35', '2012-09-09 09:40', null)
    insert into #temptimes values (1,1,'2012-09-09 09:40', '2012-09-09 09:45', null)
    insert into #temptimes values (1,1,'2012-09-09 09:45', '2012-09-09 09:55', 1)
    insert into #temptimes values (1,1,'2012-09-09 09:55', '2012-09-09 10:00', null)
    insert into #temptimes values (1,1,'2012-09-09 10:00', '2012-09-09 10:05', null)
    insert into #temptimes values (1,1,'2012-09-09 10:05', '2012-09-09 10:20', 2)

    declare @currentPeriodStart datetime
    declare @currentPeriodEnd datetime
    declare @startTime datetime
    declare @endTime datetime
    declare @lastEndTime datetime
    declare @patientId int

    declare myCurs cursor for select startTime, endTime, patientid from #tempTimes order by startTime 

    open myCurs

    fetch next from myCurs into @startTime, @endTime, @patientId

    while @@fetch_status = 0
    begin
        if @patientId is null
        begin
            if (@currentPeriodStart is null)
                set @currentPeriodStart = @startTime

            set @currentPeriodEnd = @endTime
        end else
        begin
            print   cast(@currentPeriodStart as nvarchar) + ' to ' + cast(@currentPeriodEnd as nvarchar)
            set @currentPeriodStart = null
        end

        fetch next from myCurs into @startTime, @endTime, @patientId
    end

    close myCurs
    deallocate myCurs


文章来源: Merging unused timeslots