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

次に、散在するすべての時間を、つまり30分ごとに表示するテーブルもあります(この要件のために意図的にこのテーブルを作成しました。誰かがより良いアイデアを持っている場合は、適応しようと言うことができます)。

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 専用で、私が欲しかったのはすべてのセッションです。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 に答える