5

タイムスタンプ付きのテーブルがあり、このテーブルを 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 ...

結果:

    タイムスタンプ差分
    ********* ****
    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

私がむしろ持っているもの:

    -- 時刻は現在、例として 13:40 です。

    タイムスタンプ差分
    ********* ****
    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 または 3 -- エッジ ケース、どちらでも構いません
    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(または0)
    11:40~12:40 2(または1)
    10:40~11:40 3(または2)
    09:40-10:40 4 (または 3)
4

3 に答える 3

7

DATEDIFF(minute,..単に使用してから、結果を 60 で割って整数値を取ることはできませんか。例えば

 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 ...
于 2010-07-20T11:51:50.187 に答える
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
于 2010-07-21T02:41:16.517 に答える
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) とは異なるアンカー日付を使用して直接ミリ秒計算を行うことで回避できる場合があります。

よく考えてみると、signed long には 24 日以上のミリ秒しかありません。

SELECT DateAdd(Millisecond, 2147483647, 0) = '1900-01-25 20:31:23.647'
于 2010-07-21T00:58:20.200 に答える