Warning: file_get_contents(/data/phpspider/zhask/data//catemap/5/sql/83.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
.net Linq2SQL或SQL:查找没有事件的日期_.net_Sql_Linq To Sql - Fatal编程技术网

.net Linq2SQL或SQL:查找没有事件的日期

.net Linq2SQL或SQL:查找没有事件的日期,.net,sql,linq-to-sql,.net,Sql,Linq To Sql,考虑到不同的事件可能重叠、跨越多天、在时间间隔之前开始、在时间间隔之后结束,找到在给定时间间隔内没有事件的日期的最佳方法是什么 即: 有了这些数据,我们可以看到2009年2月2日没有活动。虽然这不受时间间隔的限制,但这将为您的活动提供所有可用的间隙: declare @temp table (evt varchar(10), start datetime, [end] datetime) insert into @temp values('e1', '1/1/2009', '2/1/2009'

考虑到不同的事件可能重叠、跨越多天、在时间间隔之前开始、在时间间隔之后结束,找到在给定时间间隔内没有事件的日期的最佳方法是什么

即:


有了这些数据,我们可以看到2009年2月2日没有活动。

虽然这不受时间间隔的限制,但这将为您的活动提供所有可用的间隙:

declare @temp table (evt varchar(10), start datetime, [end] datetime)

insert into @temp values('e1', '1/1/2009', '2/1/2009')
insert into @temp values('e2', '1/15/2009', '1/31/2009')
insert into @temp values('e3', '8/15/2008', '1/16/2009')
insert into @temp values('e4', '2/3/2009', '2/15/2009');

with NextEvent as (select
    t.evt,
    tafter.evt nextEvt, 
    tafter.start start,
    tafter.[end] [end],
    ROW_NUMBER() over (order by t.evt, tafter.start) - RANK() over (order by t.evt) as number

from @temp t

left join @temp tafter on tafter.[end] >= t.[end] and tafter.evt <> t.evt)

select
    t.evt,
    t.start,
    t.[end],
    ne.nextEvt [next],
    ne.start,
    ne.[end]

from @temp t

left join NextEvent ne on ne.evt = t.evt and ne.number = 0

where ne.start > t.[end]

我不确定我是否理解你的问题。对于给定日期,您希望查看事件返回的行数

所以对于2/1/09你应该看到1,对于2/2/09你应该看到0??? SQL:

C/linq:

public class Event
        {
            public string eventID;
            public DateTime start;
            public DateTime end;
        }

        static void Main(string[] args)
        {
            IList<Event> events = new List<Event>();
            events.Add(new Event { eventID = "e1", start = new DateTime(2009, 1, 1), end = new DateTime(2009, 2, 1) });
            events.Add(new Event { eventID = "e2", start = new DateTime(2009, 1, 15), end = new DateTime(2009, 1, 31) });
            events.Add(new Event { eventID = "e3", start = new DateTime(2008, 8, 15), end = new DateTime(2009, 1, 16) });
            events.Add(new Event { eventID = "e4", start = new DateTime(2009, 2, 3), end = new DateTime(2009, 2, 15) });

            DateTime eventDate = new DateTime(2009, 2, 1);
            var available = events.Where(e => e.start.CompareTo(eventDate) < 1 && e.end.CompareTo(eventDate) > -1);
            Console.WriteLine(available.Count());

            eventDate = new DateTime(2009, 2, 2);
            available = events.Where(e => e.start.CompareTo(eventDate) < 1 && e.end.CompareTo(eventDate) > -1);
            Console.WriteLine(available.Count());

            eventDate = new DateTime(2009, 1, 16);
            available = events.Where(e => e.start.CompareTo(eventDate) < 1 && e.end.CompareTo(eventDate) > -1);
            Console.WriteLine(available.Count());
            Console.ReadLine();
        }
编辑:这并不漂亮,但此SQL将为您提供您要求的结果:

declare @temp table (evt varchar(10), start datetime, [end] datetime)
declare @result table (available datetime)

insert into @temp values('e1', '1/1/2009', '2/1/2009')
insert into @temp values('e2', '1/15/2009', '1/31/2009')
insert into @temp values('e3', '8/15/2008', '1/16/2009')
insert into @temp values('e4', '2/3/2009', '2/15/2009');

declare @start datetime
declare @end datetime
set @start = '1/1/2009'
set @end = '2/16/2009'

while @start < dateadd(day, 1, @end)
begin
    declare @rowCount int
    select @rowCount = count(*) from @temp where start <= @start and [end] >= @start
    if @rowCount = 0
        insert into @result values(@start)

    set @start = dateadd(day, 1, @start)
end
select * from @result

如果使用日期或日历类型的表,这种查询很容易。这些是使用的实用程序表,这样您就有了一个预填充的表,其中的字段在查询中计算起来会很繁琐,例如IsWeekDay、IsHoliday、FiscalMonth。下面我使用了一个非常简单的日历表。获取没有事件的日期的查询结果非常简单

这是在SQLServer2005上创建的

-- Create the #Calendar table
Create table #Calendar (CalendarDate datetime)
Set nocount on
Declare @Date smalldatetime
Set @Date = '1/1/2000'
While @Date  < '1/1/2015'
Begin
   Insert #Calendar select @Date
   Set @Date = dateadd(dd, 1, @Date)   
End

-- Create the #Event table
Create Table #Event (EventName varchar(10), StartDate datetime, EndDate datetime)

Insert Into #Event 
Select 'e1', '1/1/2009', '2/1/2009'
Union Select 'e2', '1/15/2009', '1/31/2009'
Union Select 'e3', '8/15/2008', '1/16/2009'
Union Select 'e4', '2/3/2009', '2/15/2009'

-- Return all the dates that do not have events
Select #Calendar.CalendarDate 
From #Calendar 
Left Join #Event
   on #Calendar.CalendarDate between #Event.StartDate and #Event.EndDate
Where 
   #Event.StartDate is null
   and CalendarDate between 
      (Select min(StartDate) from #Event) 
      and 
      (Select max(EndDate) from #Event)

给定一个日期范围,即:startDate 1/1/2009和endDate 2/16/2009查找所有未安排事件的日期。应返回2009年2月2日和2009年2月16日。
declare @temp table (evt varchar(10), start datetime, [end] datetime)
declare @result table (available datetime)

insert into @temp values('e1', '1/1/2009', '2/1/2009')
insert into @temp values('e2', '1/15/2009', '1/31/2009')
insert into @temp values('e3', '8/15/2008', '1/16/2009')
insert into @temp values('e4', '2/3/2009', '2/15/2009');

declare @start datetime
declare @end datetime
set @start = '1/1/2009'
set @end = '2/16/2009'

while @start < dateadd(day, 1, @end)
begin
    declare @rowCount int
    select @rowCount = count(*) from @temp where start <= @start and [end] >= @start
    if @rowCount = 0
        insert into @result values(@start)

    set @start = dateadd(day, 1, @start)
end
select * from @result
-- Create the #Calendar table
Create table #Calendar (CalendarDate datetime)
Set nocount on
Declare @Date smalldatetime
Set @Date = '1/1/2000'
While @Date  < '1/1/2015'
Begin
   Insert #Calendar select @Date
   Set @Date = dateadd(dd, 1, @Date)   
End

-- Create the #Event table
Create Table #Event (EventName varchar(10), StartDate datetime, EndDate datetime)

Insert Into #Event 
Select 'e1', '1/1/2009', '2/1/2009'
Union Select 'e2', '1/15/2009', '1/31/2009'
Union Select 'e3', '8/15/2008', '1/16/2009'
Union Select 'e4', '2/3/2009', '2/15/2009'

-- Return all the dates that do not have events
Select #Calendar.CalendarDate 
From #Calendar 
Left Join #Event
   on #Calendar.CalendarDate between #Event.StartDate and #Event.EndDate
Where 
   #Event.StartDate is null
   and CalendarDate between 
      (Select min(StartDate) from #Event) 
      and 
      (Select max(EndDate) from #Event)