sql中的连续日期和约会

sql中的连续日期和约会,sql,sql-server-2008,Sql,Sql Server 2008,我有一个sql表,其中包含工程师、应用程序日期和应用程序插槽 engineer_id, visit_date, visit_slot 1, 20/10/12, All Day 1, 21/10/12, AM 2, 20/10/12, All Day 2, 21/10/12, All Day 2, 22/10/12, All Day 3, 20/10/12,

我有一个sql表,其中包含工程师、应用程序日期和应用程序插槽

engineer_id, visit_date, visit_slot

1,           20/10/12,   All Day
1,           21/10/12,   AM
2,           20/10/12,   All Day
2,           21/10/12,   All Day
2,           22/10/12,   All Day
3,           20/10/12,   PM
3,           21/10/12,   All Day
3,           22/10/12,   PM
我想展示的是

Engineer_id, start_visit,      end_visit

1,           20/10/12 All Day, 21/10/12 AM
2,           20/10/12 All Day, 22/10/12 All Day
3,           20/10/12 PM,      21/10/12 All Day
3,           22/10/12 PM,      22/10/12 PM
我正在努力使用sql来显示预订中的中断,任何帮助都将不胜感激。
谢谢

您要做的是在数据中查找序列。通常情况下,这是一系列的天数。你的情况更难,因为你有这些时段,大概是半天

该解决方案通过将插槽转换为时间来工作。我任意使用早上6点和晚上6点。我使用
交叉连接
,因为新行是为“全天”约会创建的

有了这个数据结构,您可以使用SQL技巧来识别属于一起的插槽。其思想是按日期时间为每个工程师枚举插槽。然后从datetime中减去半天tiems枚举值。当值按顺序排列时,这是一个常量。当存在间隙时,将显示一个新值

最后,根据工程师id和组id进行分组,以获得所需的数据

下面的查询显示了这一点。它将最终结果保留为日期时间,而不是将其转换回插槽

with t as (
    select 1 as engineer_id, cast('2012-10-20' as date) as visit_date, 'All Day' as visit_slot union all
    select 1 as engineer_id, cast('2012-10-21' as date) as visit_date, 'AM' as visit_slot union all
    select 2 as engineer_id, cast('2012-10-20' as date) as visit_date, 'All Day' as visit_slot union all
    select 2 as engineer_id, cast('2012-10-21' as date) as visit_date, 'All Day' as visit_slot union all
    select 2 as engineer_id, cast('2012-10-22' as date) as visit_date, 'All Day' as visit_slot union all
    select 3 as engineer_id, cast('2012-10-20' as date) as visit_date, 'PM' as visit_slot union all
    select 3 as engineer_id, cast('2012-10-21' as date) as visit_date, 'All Day' as visit_slot union all
    select 3 as engineer_id, cast('2012-10-22' as date) as visit_date, 'PM' as visit_slot
   ),
   tslots as (
    select t2.*
    from (select t.engineer_id,
                 (CAST(visit_date as datetime) +
                      (case when t.visit_slot in ('All Day', const.slot) then const.hr/24.0 end)
                 ) as visit_datetime
          from t cross join
               (select 'AM' as slot, 6 as hr union all select 'PM', 18) const
         ) t2
    where visit_datetime is not null
    group by engineer_id, visit_datetime
   )
select engineer_id, MIN(visit_datetime) as min_datetime, MAX(visit_datetime) as max_datetime
from (select ts.*,
             ROW_NUMBER() over (partition by engineer_id order by visit_datetime) as seqnum,
             visit_datetime - 0.5*(ROW_NUMBER() over (partition by engineer_id order by visit_datetime)) as groupid
      from tslots ts
     ) ts1
group by engineer_id, groupid
order by 1, 2   

哪种关系数据库管理系统?sql server?或者oracle?到目前为止,您有sql代码吗?如果是的话,把它贴出来,不知道你说的“预订中断”是什么意思?对于每个工程师id,除了获得
min(访问日期)
max(访问日期)
之外还有更多吗?我使用的是SQL 2008,是的,不仅仅是获得min和max,如果你看工程师3,他在2012年10月22日没有预订AM,因此有两个条目。谢谢,这太棒了!不过,我可以扩展一下吗?可能会有夜班和夜班的情况,因此一些工程师可能会连续夜班而不是白天。我如何将其合并?:)事实上,我想在答案中加上这个。您需要添加日历表,因为有些天可能不是工作日(周末、节假日)。您在原始问题中没有指定此限制,但解决此问题的唯一方法是使用日历。为了处理工程师一天中的不同时间,我建议将针对不同工程师的查询作为单独的查询。然后试着把它们合并成一个。谢谢,但我不太清楚你的意思,即使有银行假期和周末,它们也不属于非工作日,它们可以被分配工作。