1

我有一个似乎很复杂的问题。我需要知道在某一天某个时间的某个会话中会发生什么。

简而言之,我有一张表格,可以显示给定区域的所有会话。这些会话具有开始日期、开始时间和结束时间。

您可以在此表中看到:

idArea | idSession |  startDate  |    startTime        |    endTime  
   1   |    1      |  2013-01-01 | 1900-01-01 09:00:00 | 1900-01-01 12:00:00
   1   |    2      |  2013-01-01 | 1900-01-01 14:00:00 | 1900-01-01 15:00:00
   1   |    3      |  2013-01-04 | 1900-01-01 09:00:00 | 1900-01-01 13:00:00
   1   |    4      |  2013-01-07 | 1900-01-01 10:00:00 | 1900-01-01 12:00:00
   1   |    5      |  2013-01-07 | 1900-01-01 13:00:00 | 1900-01-01 18:00:00
   1   |    6      |  2013-01-08 | 1900-01-01 10:00:00 | 1900-01-01 12:00:00

然后我还有一个表格,显示所有时间穿插,即每半小时一次(我故意为此要求创建此表格,如果有人有更好的想法,我可以说我会尝试适应)。

idHour |   Hour
   1   |   1900-01-01 00:00:00
   2   |   1900-01-01 00:30:00
   3   |   1900-01-01 01:00:00
  ............................
   4   |   1900-01-01 09:00:00
   5   |   1900-01-01 09:30:00
   6   |   1900-01-01 10:00:00
   7   |   1900-01-01 10:30:00
  ............................

最后,我想呈现的是这样的:

  startDate  |    startTime        |    SessionID
  2013-01-01 | 1900-01-01 09:00:00 |        1
  2013-01-01 | 1900-01-01 09:30:00 |        1
  2013-01-01 | 1900-01-01 10:00:00 |        1
  2013-01-01 | 1900-01-01 10:30:00 |        1
  2013-01-01 | 1900-01-01 11:00:00 |        1
  2013-01-01 | 1900-01-01 11:30:00 |        1
  2013-01-01 | 1900-01-01 11:30:00 |        1
  2013-01-01 | 1900-01-01 14:00:00 |        1
  2013-01-01 | 1900-01-01 14:30:00 |        1
  2013-01-01 | 1900-01-01 15:00:00 |        1

该表仅适用于 idSession=1 我想要的所有会话。如果一天没有会话可以返回 NULL。

这个查询或程序的难点在于,当该区域有会话时,他们必须向我展示一个月中的所有日子。

为此,我已经使用了这个查询:

;WITH t1 AS 
(
    SELECT  
        startDate,
        DATEADD(MONTH, DATEDIFF(MONTH, '1900-01-01', startDate), '1900-01-01') firstInMonth,
        DATEADD(DAY, -1, DATEADD(MONTH, DATEDIFF(MONTH, '1900-01-01', startDate) + 1, '1900-01-01')) lastInMonth,
        COUNT(*) cnt
    FROM    
        @SessionsPerArea
    WHERE
        idArea = 1
    GROUP BY
        startDate
), calendar AS
(
    SELECT DISTINCT 
        DATEADD(DAY, c.number, t1.firstInMonth) d
    FROM    
        t1 
    JOIN
        master..spt_values c ON type = 'P'
                             AND DATEADD(DAY, c.number, t1.firstInMonth) BETWEEN t1.firstInMonth AND t1.lastInMonth
)
SELECT  
    d date, 
    cnt Session
FROM
    calendar c
LEFT JOIN 
    t1 ON t1.startDate = c.d

这很复杂,如果有人有简单的方法来做到这一点,那就太好了。

4

2 回答 2

1

如果我理解正确,这只是日历表和@SessionPerArea 之间的连接,条件正确:

select spa.StartDate, c.hour as StartTime, spa.idSession as SessionId
from calendar c join
     @SessionsPerArea spa
     on c.hour between spa.startTime and spa.EndTime

连接匹配数据中开始时间和结束时间之间的所有时间,然后返回值。

于 2013-03-28T19:01:21.903 回答
0

我想也许你只需要在日历和@SessionsPerArea 之间进行外部连接......所以无论与@SessionsPerArea 表是否匹配,都会返回日历表中的所有日期?

于 2013-04-01T18:44:48.363 回答