日時文字列に1ミリ秒を追加する方法は?


15

選択に基づいて、次のようにx行を返すことができます。

1   2019-07-23 10:14:04.000
1   2019-07-23 10:14:11.000
2   2019-07-23 10:45:32.000
1   2019-07-23 10:45:33.000

ミリ秒はすべて0です。

1ミリ秒ごとに1を追加する方法があるので、選択は次のようになります。

1   2019-07-23 10:14:04.001
1   2019-07-23 10:14:11.002
2   2019-07-23 10:45:32.003
1   2019-07-23 10:45:33.004

カーソルを作成しようとしていますが、成功していません。

これは、必要な結果を取得するためのクエリです。

  select top 10 ModifiedOn 
    from [SCHEMA].[dbo].[TABLE]
  where FIELD between '2019-07-23 00:00' and '2019-07-23 23:59'

81kの値があります。フィールドはDATETIMEです。


2
行1に1ミリ秒、行2に2ミリ秒、行3に3ミリ秒などを追加しようとしていますか?
ジョンイスブレナー

回答:


33

Datetime1ミリ秒のレベルでは正確ではありません。別のデータ型に変更しない限り(つまりdatetime2)、求めていることはできません。

ドキュメンテーション

重要な引用:

.000、.003、または.007秒の増分に丸められた精度


13

DateAdd関数は、あなたが探しているものです。

millisecond関数の最初のパラメーターとして使用して、ミリ秒を追加していることを通知します。次に1、追加するミリ秒数の2番目のパラメーターとして使用します。

次に例を示します。現在の時刻を変数に取り込み、1ミリ秒を追加して結果を2番目の変数として保存してから、各変数を出力します

Declare @RightNow as DateTime2
Declare @RightNowPlusAMillisecond as DateTime2

Select @RightNow = Getdate()
Select @RightNowPlusAMillisecond = DateAdd(millisecond,1,@RightNow)

Print @RightNow
Print @RightNowPlusAMillisecond

結果:

2019-07-23 08:25:38.3500000
2019-07-23 08:25:38.3510000

注意:

フォレストが別の答えで指摘しているように、datetimeデータ型はミリ秒の精度を保証しません。.000、.003、または.007秒の増分に丸められます。ミリ秒の精度が必要な場合は、を使用しますdatetime2


13

@ダグデデンには正しい出発点がありますが、質問の元々の意図だと思ったもの、つまり行ごとにミリ秒を増やして結果セットに適用する方法に答えたいと思いました。

その場合、ROW_NUMBER共通テーブル式を使用できます(結合など、テーブル構造に応じて必要に応じて編集します)。

値を表示するために選択します:

;WITH CTE AS (
SELECT t.my_id, t.my_date_column, ROW_NUMBER() OVER (ORDER BY my_date_column, my_id DESC) AS R
FROM Table1 t
)
SELECT TOP 1000 *, DATEADD(MILLISECOND, R, CAST(my_date_column AS datetime2)) [new_date]
FROM CTE
ORDER BY my_date_column

結合を更新して元のテーブルに戻します。

;WITH CTE AS (
SELECT t.my_id, t.my_date_column, ROW_NUMBER() OVER (ORDER BY my_date_column, my_id DESC) AS R
FROM Table1 t
)
UPDATE t SET 
my_date_column = DATEADD(MILLISECOND, R, CAST(my_date_column AS datetime2))
FROM CTE c
     JOIN Table1 t ON c.my_id = t.my_id

このCTEは更新可能です。に参加する必要はありませんTable1。ちょうどUPDATE CTE SET my_date_column =...
スティーブンヒブル

4

私はそれを使用してそれをやったDATETIME2(3)

以下のクエリで見ることができるように、それはもっとeconomicです:

declare @dt1 datetime2(3)
declare @dt2 datetime2

SELECT @DT1 = SYSDATETIME()
SELECT @DT2=  SYSDATETIME()

SELECT [THE LENGTH OF DATETIME2]=DATALENGTH(@DT2)
      ,[THE LENGTH OF DATETIME2(3)]=DATALENGTH(@DT1)

ここに画像の説明を入力してください

との違いはdatetimeここでdatetime2説明されています

この演習では、テスト用の一時テーブルを作成random dates01-jan-2019、現在とは異なる999を使用してデータを設定します(23-july-2019

そして順番に、ミリ秒を1から999に設定しました

SET NOCOUNT ON
SET TRANSACTION ISOLATION LEVEL READ UNCOMMITTED
SET NOEXEC OFF

IF OBJECT_ID ('TEMPDB..#T1') IS NOT NULL
   DROP TABLE #T1

CREATE TABLE #t1(the_date DATETIME2(3) NOT NULL PRIMARY KEY CLUSTERED )
GO

-- run this 999 times - hopefully there will be no duplicates
-- SELECT 204*24*60*60 - today is 23-july-2019 - the 203rd day of the year
    DECLARE @DT DATETIME2(3)
    SELECT @DT = CONVERT(DATETIME2(3),
           DATEADD(SECOND, ABS(CHECKSUM(NEWID()) % 17625600), 
                   '2019-01-01'),120) 

    --SELECT @DT

    IF NOT EXISTS( SELECT 1 FROM #T1 WHERE THE_DATE = @DT) 
    INSERT INTO #T1 VALUES (@DT)
GO 999


--check it out what we have
SELECT * FROM #T1

--get the date and the new date
SELECT 
 THE_DATE
,THE_NEW_DATE= DATEADD(MILLISECOND, ROW_NUMBER() OVER (ORDER BY THE_DATE), THE_DATE ) 
 FROM #T1

これは私が得るものです:(部分的なビュー)

ここに画像の説明を入力してください


2

他のポスターの1つは正しいです。DATETIME(T-SQLでは)ミリ秒の精度ではありません(センチ秒の精度です)。

そのレベルの精度を実現するには、を使用しますDATETIME2

文字列datetimeをに変換してからdatetime21ミリ秒を追加し、最後に文字列に戻す例を次に示します。

select convert(
            varchar(MAX), --in T-SQL, varchar length is optional
            dateadd(
                millisecond,
                1,
                convert(
                    datetime2,
                    '2019-07-23 12:01:23.11'
                )
            )
        )

弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.