2012-04-20 9 views
2

DateTime値を保持するScheduledTime列がこのテーブルにあります。これらは開始時刻が 3時間です。上記の日時値は、3時間のテストのための時間を開始しているタイムスロット列を取得する(SQLクエリ)

SELECT ScheduledTime from Schedule; 

2012-03-16 16:34:36.000 
2012-03-16 16:34:36.000 
2012-03-16 16:34:36.000 
2012-03-16 16:34:36.000 
2012-03-16 16:34:36.000 
2012-03-16 16:34:36.000 
2012-03-16 16:34:36.000 
2012-03-16 16:34:36.000 
2012-03-20 09:14:48.000 
2012-03-20 13:14:48.000 
2012-03-20 17:14:48.000 
2012-03-20 21:14:48.000 
2012-04-14 17:13:19.000 
2012-04-14 21:13:19.000 
2012-04-15 01:13:19.000 
2012-04-15 05:13:19.000 
2012-04-15 09:13:19.000 
2012-04-15 13:13:19.000 
2012-04-15 17:13:19.000 
2012-04-15 21:13:19.000 
2012-04-16 01:13:19.000 
2012-04-16 05:13:19.000 
2012-04-16 13:13:19.000 
2012-04-16 17:13:19.000 
2012-04-17 01:13:19.000 
2012-04-17 05:13:19.000 
2012-04-17 13:13:19.000 
2012-04-18 18:29:16.000 
2012-04-19 15:48:12.000 
2012-04-19 19:10:00.000 
2012-04-19 23:47:00.000 
2012-04-20 10:27:28.000 
2012-04-20 17:27:00.000 

: 列には、次のようになります。だから私は3時間のテストのために次の利用可能なスロットを取得する必要があります。既存のテストやcurrentTime + 1時間以内に対応できる場合はベストでしょう。

タスクは、ScheduledTime列から取得した3時間スロットの開始時間を保持する列(SlotsColumn)を生成することです。SlotsColumn値は> {fn Now()}つまりCurrentTimeです。

オプションは、2008年

I have tried this: 
WITH rows AS 
     (
     SELECT *, ROW_NUMBER() OVER (ORDER BY [ScheduledTime]) AS rn 
     FROM [dbo].[Schedule] 
     WHERE [ScheduledTime] IS NOT NULL    
     ) 
SELECT TOP(1) 
DATEADD(second,10800, mc.ScheduledTime) AS NextTime 
FROM rows mc 
JOIN rows mp 
ON  mc.rn = mp.rn - 1 
WHERE (DATEDIFF(SECOND, mc.ScheduledTime, mp.ScheduledTime) - 10800) >= 10800 
order by mc.ScheduledTime DESC 

SQL Serverを使用してクエリが中1つの有効な開始時刻のリストを返し、それがどのような値を持っていない場合、それは1時間に+

をCurrentTimeをを与えるべきであるということです未来、それが存在する場合のみ。

上記のサンプルデータには、 '2012-04-20 03:47:00.000'が返されます。これは '2012-04-20 17:27:00.000'に別のテストがあるとは考えていないため間違っています'重複してはいけません。 希望の出力は「2012-04-20 12:27:00.000」となります。「2012-04-20 10:27:28.000」のテストの後、「2012-04-20」のテストの前です17 :27:00.000 '、3時間のテストのための完全なスロット。 私のCurrentTimeは '2012-04-20 11:45:23.393'

有効時間が存在しない場合、CurrentTime + 1時間を返すようにするにはどうすればよいですか?

これはC#で実行できますが、SQLクエリを試行しています。

ヘルプ/ヒントをお願いします。

+1

何を試しましたか?希望の出力を添付してください。 'id'のような別の列があり、' id'が 'ScheduledTime'によってソートされていますか? – fancyPants

+0

'ScheduledTime'のすべてのインスタンスを見つけるためには、それらの後ろに3hrの明確なウィンドウを持つクエリが必要です。クリアウィンドウが見つからない場合、CurrentTime + 1hrを返しますか? – Paddy

+0

が、私はこれをしようとしています。 を '行の \t \t( \t \t SELECT * [ScheduledTime] BY、ROW_NUMBER()OVER(ORDER)[DBO] FROM \t \t AS RN AS [スケジュール] \t \t [ScheduledTime] \t \t \t \t \t \t NULLされていない)NextTimeAS DATEADD(第2、10800、mc.ScheduledTime)を選択 WHERE(DATEDIFF(SECOND、mc.ScheduledTime、mp.ScheduledTime) - - 10800)> = 10800 AND DATEADD(第2、10800、MC行MC FROM行が ON mc.rn = mp.rn融点JOIN。 ScheduleTime)> {fn Now()} mc.ScheduledTime' はいScheduleIDがあります。 あなたの質問は「次にScheduledTimeでソートされたIDですか」と表示されませんでした。 – dushyantp

答えて

0

最後に勤務し、望ましい結果を達成したクエリは次のとおりです。

WITH rows AS 
       (
       SELECT *, ROW_NUMBER() OVER (ORDER BY [ScheduledTime]) AS rn 
       FROM Schedule 
       WHERE [ScheduledTime] IS NOT NULL      
       ) 
    SELECT COALESCE 
      ( 
      (
      SELECT Top 1 
      DateAdd(SECOND,-10800,mp.ScheduledTime) AS NewNextTime 
      FROM rows mc 
      JOIN rows mp 
      ON  mc.rn = mp.rn - 1 
      WHERE (DATEDIFF(SECOND, mc.ScheduledTime, mp.ScheduledTime) - 10800) >= 10800 
      And mp.ScheduledTime >= GETDATE() 
      And DateAdd(SECOND,-10800,mp.ScheduledTime)>= GETDATE() 
      order by mc.ScheduledTime 
      ), 
      ( 
      SELECT TOP 1 
        DATEADD(hour, 3, scheduledTime) AS NewNextTime 
      FROM Schedule s 
      WHERE s.scheduledTime >= DATEADD(hour, -3, GetDate()) 
        AND NOT EXISTS 
        ( 
        SELECT NULL 
        FROM Schedule sn 
        WHERE sn.scheduledTime > s.scheduledTime 
          AND sn.scheduledTime < DATEADD(hour, 6, s.scheduledTime) 
        ) 

      ORDER BY 
        scheduledTime 
      ), 
      (
       SELECT TOP 1 
       DATEADD(SECOND, (3600), GetDate()) AS NewNextTime 
      ) 
      ) 

これが最後のテストの終了後の時間を有効時間を返すか、最悪のシナリオで。

SELECT COALESCEの最初の部分は、既存のスロット内からタイムスロットを返します。 SELECT COALESCEの2番目の部分は、すべてのテストスロットの最後にタイムスロットを返します。 SELECT COALESCEの3番目の部分は、CurrentTime + 1hrとして返されます。

これについての議論は、皆さんがこれに到達するのに非常に役立ちました。私はまだこれを使用するように、より良い提案を探します。

P.S.このソリューションを投稿するのが遅れて申し訳ありません。

1
DECLARE @now DATETIME2 = '2012-04-20 11:45:23.393' 
DECLARE @schedule TABLE 
     (
     ScheduledTime DATETIME2 NOT NULL 
     ) 

INSERT 
INTO @schedule 
VALUES 
('2012-03-16 16:34:36.000'), 
('2012-03-16 16:34:36.000'), 
('2012-03-16 16:34:36.000'), 
('2012-03-16 16:34:36.000'), 
('2012-03-16 16:34:36.000'), 
('2012-03-16 16:34:36.000'), 
('2012-03-16 16:34:36.000'), 
('2012-03-16 16:34:36.000'), 
('2012-03-20 09:14:48.000'), 
('2012-03-20 13:14:48.000'), 
('2012-03-20 17:14:48.000'), 
('2012-03-20 21:14:48.000'), 
('2012-04-14 17:13:19.000'), 
('2012-04-14 21:13:19.000'), 
('2012-04-15 01:13:19.000'), 
('2012-04-15 05:13:19.000'), 
('2012-04-15 09:13:19.000'), 
('2012-04-15 13:13:19.000'), 
('2012-04-15 17:13:19.000'), 
('2012-04-15 21:13:19.000'), 
('2012-04-16 01:13:19.000'), 
('2012-04-16 05:13:19.000'), 
('2012-04-16 13:13:19.000'), 
('2012-04-16 17:13:19.000'), 
('2012-04-17 01:13:19.000'), 
('2012-04-17 05:13:19.000'), 
('2012-04-17 13:13:19.000'), 
('2012-04-18 18:29:16.000'), 
('2012-04-19 15:48:12.000'), 
('2012-04-19 19:10:00.000'), 
('2012-04-19 23:47:00.000'), 
('2012-04-20 10:27:28.000'), 
('2012-04-20 17:27:00.000') 

SELECT COALESCE 
     (
     (
     SELECT TOP 1 
       DATEADD(hour, 3, scheduledTime) 
     FROM @schedule s 
     WHERE s.scheduledTime >= DATEADD(hour, -3, @now) 
       AND NOT EXISTS 
       (
       SELECT NULL 
       FROM @schedule sn 
       WHERE sn.scheduledTime > s.scheduledTime 
         AND sn.scheduledTime < DATEADD(hour, 6, s.scheduledTime) 
       ) 

     ORDER BY 
       scheduledTime 
     ), 
     DATEADD(hour, 1, @now) 

-- This is redundant 

     ) 
+0

上記のクエリはCurrentTime + 1hrを常に返すようです。 私に対してそれを実行しようとした: '2012-04-20 14:20:40.183' ' 2012-04-20 17:27:00.000' '2012-04-20 23:27:00.000' をCurrentTimeは2012-04-20 13:29:20.177で、2012-04-20 14:29:32.467を返します。2012-04-20 20:27:32.467の周りに戻る必要があります。 興味深いことに、私はこのタイプのクエリを知りませんでした。ありがとう。私はこの行についてさらに調査中です。 – dushyantp

+0

@ dushyantp:ポストアップデートを参照 – Quassnoi

+0

この変更により、最悪ケース時間が常に戻されます。 2012-04-20 23:27:00.000、2012-04-21 02:27:00.000 2012年4月1日05:27:00.000を返します。この時点では予定されていませんCurrentTime + 1、それはそれを返す必要があります。 しかし、これは非常に役に立ちます。私は解決策に到達するためにあなたのこのクエリを微調整することができると思う。 – dushyantp

関連する問題