我有以下表结构:
CREATE TABLE [dbo].[ReservationDetails]
(
[SessionID] [int] IDENTITY(1,1) NOT NULL,
[UserID] [bigint] NOT NULL,
[ExpectedStart] [datetime] NOT NULL,
[ExpectedEnd] [datetime] NOT NULL,
CONSTRAINT [PK_dbo.ReservationDetails]
PRIMARY KEY CLUSTERED ([SessionID] ASC)
) ON [PRIMARY]
以下是一些数据:
INSERT INTO ReservationDetails (UserID,ExpectedStart,ExpectedEnd)
VALUES (1, '1900-01-01 09:15:00.000', '1900-01-01 09:30:00.000'),
(2, '1900-01-01 10:00:00.000', '1900-01-01 10:30:00.000')
从上表&数据,我想在上午9点到11点半之间找到可用的时段。
此处UserID = 1
已预订时间为09:15 AM至09:30 AM&
UserID = 2
预订时间为上午10:00至上午10:30
我需要在09:00 AM到11:30 AM之间列出可能的免费/可用时段。我们只需要显示空闲/可用时间就没有时隙定时。
它们如下所示。
09:00 AM TO 09:15 AM
09:30 AM TO 10:00 AM
10:30 AM TO 11:30 AM
我需要帮助才能获得免费/可用的广告位
答案 0 :(得分:4)
这是一个空白和岛屿类型的问题。
请谷歌了解更多信息。
这是 example solution :
declare @startTime datetime= '1900-01-01 09:00:00.000', @EndTime datetime='1900-01-01 11:30:00.000';
;
with allts as
(
select top (select datediff(mi,@startTime,@EndTime)+1)
mislot=dateadd(mi,row_number() over(order by (select null))-1,@startTime),
rn=row_number() over(order by (select null))
from
sys.objects t1 cross join
sys.objects t2
),
ts as
( select a.mislot,a.rn, rn2= row_number() over ( order by rn asc)
from allts a
outer apply(
select flag=1 from ReservationDetails r
where a.mislot > ExpectedStart and a.mislot < ExpectedEnd
)b
where b.flag is null
)
select startavl=min(mislot), endavl=max(mislot) from ts
group by rn2-rn
order by startavl asc
答案 1 :(得分:0)
对于c#中的解决方案,我有以下代码。我没有测试过它们。 我们的想法是声明一个包含(持续时间分钟)条目的数组列表。 你有一个对象,在这个对象上你可以阻止时隙。如果阻止插槽,则数组列表中的条目将在此分钟设置为false。 要获得空闲时间段,您可以遍历列表。每次如果在假之后存在真实,则您有空闲时段的开始时间。插槽是空闲的,直到下一个假(空闲插槽的结束时间)。所以你可以获得免费插槽。
namespace xy
{
class test
{
List<bool> slots = new List<bool>();
DateTime start;
DateTime end;
public test(DateTime start, DateTime end)
{
this.start = start;
this.end = end;
for(int i=1; i <= (end.Hour * 60) + end.Minute; i++)
{
slots.Add(true);
}
}
public void Block_Slots(DateTime startBlock, DateTime endBlock)
{
for(int i = (startBlock.Hour * 60) + startBlock.Minute; i<= (endBlock.Hour * 60) + endBlock.Minute; i++)
{
slots[i] = false;
}
}
public List<Slot> GetFreeSlots()
{
List<Slot> tmp = new List<Slot>();
Nullable<DateTime> startPeriod = null;
Nullable<DateTime> endPeriod = null;
int counter = 1;
foreach(bool entry in slots)
{
if (entry)
{
if(startPeriod == null)
startPeriod = new DateTime(this.start.Year, this.start.Month, this.start.Day, counter / 60 + start.Hour, counter % 60 + start.Minute, 0);
else
{
}
}
else
{
if(startPeriod != null)
{
endPeriod = new DateTime(this.start.Year, this.start.Month, this.start.Day, counter-1 / 60, counter-1 % 60, 0);
tmp.Add(new Slot((DateTime)startPeriod, (DateTime)endPeriod));
startPeriod = null;
endPeriod = null;
}else{}
}
counter++;
}
return tmp;
}
}
class Slot
{
DateTime start;
DateTime end;
public Slot(DateTime start, DateTime end)
{
this.start = start;
this.end = end;
}
}
}