5


0

T-SQL DateDiff-「00分になった回数」ではなく「1時間前」にパーティション分割

タイムスタンプ付きのテーブルがあり、このテーブルを1時間の間隔に分割します。今から数時間前に戻ります。 T-SQL DATEDIFF関数では、分針が通過する回数をカウントするため、必要な結果を取得できません。 2つの日付の間の12-タイムスタンプと現在の間で、分針が_現在の場所を通過する回数が必要です。

T-SQLでこれを行う簡単な方法はありますか?

*更新:*コメントに対する応答として、サンプルデータ、現在使用しているクエリ、取得している結果、および必要な結果を示します。

サンプルデータ:

TimeStamp
*********
2010-07-20 11:00:00.000
2010-07-20 10:44:00.000
2010-07-20 10:14:00.000
2010-07-20 11:00:00.000
2010-07-20 11:40:00.000
2010-07-20 10:16:00.000
2010-07-20 13:00:00.000
2010-07-20 12:58:00.000

現在のクエリ:

SELECT TimeStamp, DATEDIFF(HOUR, TimeStamp, CURRENT_TIMESTAMP) AS Diff FROM ...

結果:

    TimeStamp                   Diff
    *********                   ****
    2010-07-20 11:00:00.000     2
    2010-07-20 10:44:00.000     3
    2010-07-20 10:14:00.000     3
    2010-07-20 11:00:00.000     2
    2010-07-20 11:40:00.000     2
    2010-07-20 10:16:00.000     3
    2010-07-20 13:00:00.000     0
    2010-07-20 12:58:00.000     1

私が欲しいもの:

    -- The time is now, for the sake of the example, 13:40

    TimeStamp                   Diff
    *********                   ****
    2010-07-20 11:00:00.000     3 -- +1
    2010-07-20 10:44:00.000     3
    2010-07-20 10:14:00.000     4 -- +1
    2010-07-20 11:00:00.000     3 -- +1
    2010-07-20 11:40:00.000     2 or 3 -- edge case, I don't really care which
    2010-07-20 10:16:00.000     4 -- +1
    2010-07-20 13:00:00.000     1 -- +1
    2010-07-20 12:58:00.000     1

変更した結果を「+1」でマークしました。 また、これが0インデックスか1インデックスかはあまり気にしませんが、基本的には13:40になったら同じ値を取得するタイムスパンが

    12:40-13:40    1 (or 0)
    11:40-12:40    2 (or 1)
    10:40-11:40    3 (or 2)
    09:40-10:40    4 (or 3)

3 Answer


7


`DATEDIFF(minute、..`を使用してから、結果を60で除算して整数値を取得することはできません。 e.g.

 SELECT DATEDIFF(minute, '2010-07-20 06:00', GETDATE())/60

datediffがintを返すため、これは暗黙的にintとしてキャストされ、丸められずに1時間全体が得られると思います。

更新された投稿から正確なクエリを使用するには:

SELECT TimeStamp, (DATEDIFF(minute, TimeStamp, CURRENT_TIMESTAMP) /60) AS Diff FROM ...


0


これでグループ化できます:

SELECT DateDiff(Hour, 0, GetDate() - TimeStamp)

これが表す時間を知りたい場合は、計算し直してください:

DateAdd(Hour, -DateDiff(Hour, 0, GetDate() - TimeStamp), GetDate())

日付の減算が気に入らない場合、それでも実行できますが、少し難しくなります。 暗闇で撮影する代わりに、これが正しいことを証明するためにクエリを作成しました。

SELECT
   TimeStamp,
   Now = GetDate(),
   HourDiff = DateDiff(Hour, 0, GetDate() - TimeStamp),
   HourCalc = DateAdd(Hour, -DateDiff(Hour, 0, GetDate() - TimeStamp), GetDate()),
   HourDiff2 = DateDiff(Hour, DateAdd(Millisecond, AdjustMs, TimeStamp), DateAdd(Millisecond, AdjustMs, GetDate())),
   HourCalc2 = DateAdd(Hour, -DateDiff(Hour, DateAdd(Millisecond, AdjustMs, TimeStamp), DateAdd(Millisecond, AdjustMs, GetDate())), GetDate())
FROM
   (
      SELECT DateAdd(Second, -3559, GetDate())
      UNION ALL SELECT DateAdd(Second, -3600, GetDate())
      UNION ALL SELECT DateAdd(Second, -3601, GetDate())
   ) x (TimeStamp)
   CROSS JOIN (
      SELECT 3599997 - DateDiff(Millisecond, 0, DateAdd(Hour, -DateDiff(Hour, 0, GetDate()), GetDate()))
   ) D (AdjustMs)

残念ながら、datetimeデータ型の解像度(1/300秒)に関する知識を活用する必要があったため、3600000-3 = 3599997です。 ミリ秒の調整がGetDate()の代わりにTimeStampに基づいて計算された場合、これは必要ありませんが、派生テーブルD内の大きな式をメインクエリで2回使用する必要があるため、かなり面倒ですAdjustMs。

ランダムな日付間のミリ秒の差を計算することはできないか、オーバーフローエラーが発生するため、計算は必要と思われるよりも複雑です。 可能な日付範囲がわかっている場合は、「19000101 00:00:00.000」(上記の式の0)とは異なるアンカー日付を使用して直接ミリ秒の計算を行うことで回避できる場合があります。

考え直せば、24ミリ秒以上の署名付きlongを取得できます。

SELECT DateAdd(Millisecond, 2147483647, 0) = '1900-01-25 20:31:23.647'


0


私は使うだろう

FLOOR(24 * CAST(CURRENT_TIMESTAMP-[TimeStamp] as float))

テストケース

DECLARE @GetDate datetime
set @GetDate = '2010-07-20 13:40:00.000';

WITH TestData As
(
select CAST('2010-07-20 11:00:00.000' AS DATETIME) AS [TimeStamp]  UNION ALL
select '2010-07-20 10:44:00.000'  UNION ALL
select '2010-07-20 10:14:00.000'  UNION ALL
select '2010-07-20 11:00:00.000'  UNION ALL
select '2010-07-20 11:40:00.000'  UNION ALL
select '2010-07-20 10:16:00.000'  UNION ALL
select '2010-07-20 13:00:00.000'  UNION ALL
select '2010-07-20 12:58:00.000'
)

SELECT [TimeStamp], FLOOR(24 * CAST(@GetDate-[TimeStamp] as float))  AS Diff
FROM TestData

結果

(投稿した正確な結果を得るには1を追加する必要がありますが、インデックス付けされた0または1について気にしないと言います)

TimeStamp               Diff
----------------------- ----------------------
2010-07-20 11:00:00.000 2
2010-07-20 10:44:00.000 2
2010-07-20 10:14:00.000 3
2010-07-20 11:00:00.000 2
2010-07-20 11:40:00.000 2
2010-07-20 10:16:00.000 3
2010-07-20 13:00:00.000 0
2010-07-20 12:58:00.000 0