选择不在时间范围内的表中的值

时间:2014-07-02 23:09:16

标签: sql sql-server

我有两张桌子(简化版):

create table Schedule(
Id int,
ScheduledData datetime,
UserId int)

create table User(
Id int,
Name varchar(50))

在第一个表格中,我存储了所有预定会议,并将其链接到用户。

我想要的是检索用户拥有的所有空闲时间。它不必非常详细。

例如,如果用户没有安排在2014年2月7日上午(早于12:59:59)召开会议,则显示一行,其中包含用户的姓名和日期。如果他有一个自由的下午也一样。

我到目前为止所尝试的并且无法工作的是创建一个临时表,并将其填入本月的所有日期以及我的数据库中的所有用户。使用CTE很有效:

create table #Temp(
StartData datetime,
EndDate datetim,
UserId int)

然后,我这样做是为了显示行:

select U.Name, X.ScheduledDate
from #Temp T
left outer join 
(select S.UserId
from Schedules S
where ScheduledData between @X and @Y) X on T.UserId = S.UserId
left outer join User U on T.UserId = U.Id
where S.ScheduledDate between T.StartDate and T.EndDate

它没有奏效,我无法理解它。我整天都在苦苦挣扎,这是迄今为止我所做过的最好的事情。

1 个答案:

答案 0 :(得分:0)

问题可能会使用更多规范:

  • 'Schedule'中的一行是什么意思? 'ScheduledData'列只是一个瞬间;这是会议的开始时间吗?会议有多长时间?
  • 显示“所有用户的空闲时间?”是什么意思?时间是连续的(好的,有点的)数量。如何表示结果?

在给定一段时间的情况下,您的示例的精神似乎会返回关于会议是否在该时间发生的真/假值。假设您有一个名为“Users”的表,其中包含每个用户的ID。如何创建一个包含三列'id','start_time'和'end_time'的表'time_segments';你可以定义你想要的任何时间段,例如你的'morning'块,然后用以下内容获取空闲时间:

select UserId,all_slots.id
from
( select
    TimeSegments.id, UserId
  from
    TimeSegments
    cross join Users ) all_slots
left outer join
( select
    TimeSegments.id, UserId
  from
    Schedule
    cross join TimeSegments
  where
    Schedule.datetime between TimeSegments.start_time and TimeSegments.end_time
) booked using(id, UserId)
where
  booked.UserID is null