2 つの日付の間の値をDATETIME
持つ TSQLの列を含むテーブルを更新する最も簡単な方法は何ですか?RANDOM
ORDER BY DATE
それに関連するさまざまな投稿を目にしますが、更新後にランダム値が実際に連続しています。
最初に、日時の範囲を定義する開始日時列と終了日時列を持つテーブルを含むデータベースがあるとします。
CREATE DATABASE StackOverflow11387226;
GO
USE StackOverflow11387226;
GO
CREATE TABLE DateTimeRanges (
StartDateTime DATETIME NOT NULL,
EndDateTime DATETIME NOT NULL
);
GO
ALTER TABLE DateTimeRanges
ADD CONSTRAINT CK_PositiveRange CHECK (EndDateTime > StartDateTime);
また、テーブルに次のデータが含まれているとします。
INSERT INTO DateTimeRanges (
StartDateTime,
EndDateTime
)
VALUES
('2012-07-09 00:30', '2012-07-09 01:30'),
('2012-01-01 00:00', '2013-01-01 00:00'),
('1988-07-25 22:30', '2012-07-09 00:30');
GO
次のSELECT
ステートメントは、開始日時、終了日時、および開始日時以上で 2 番目の日時未満の分の精度を持つ疑似ランダム日時を返します。
SELECT
StartDateTime,
EndDateTime,
DATEADD(
MINUTE,
ABS(CHECKSUM(NEWID())) % DATEDIFF(MINUTE, StartDateTime, EndDateTime) + DATEDIFF(MINUTE, 0, StartDateTime),
0
) AS RandomDateTime
FROM DateTimeRanges;
この関数は非決定的であるため、NEWID()
実行ごとに異なる結果セットが返されます。今生成した結果セットは次のとおりです。
StartDateTime EndDateTime RandomDateTime
----------------------- ----------------------- -----------------------
2012-07-09 00:30:00.000 2012-07-09 01:30:00.000 2012-07-09 00:44:00.000
2012-01-01 00:00:00.000 2013-01-01 00:00:00.000 2012-09-08 20:41:00.000
1988-07-25 22:30:00.000 2012-07-09 00:30:00.000 1996-01-05 23:48:00.000
列 RandomDateTime のすべての値は、列 StartDateTime と EndDateTime の値の間にあります。
ランダムな値を生成するこの手法は、Jeff Moden によるものです。彼は、SQL Server Central でデータ生成に関する素晴らしい記事を書きました。より詳細な説明については、それをお読みください。登録が必要ですが、それだけの価値があります。
アイデアは、開始日時からランダムなオフセットを生成し、開始日時にオフセットを追加して、開始日時と終了日時の間に新しい日時を取得することです。
この式DATEDIFF(MINUTE, StartDateTime, EndDateTime)
は、開始日時と終了日時の間の合計分数を表します。オフセットは、この値以下でなければなりません。
この式ABS(CHECKSUM(NEWID()))
は、行ごとに独立したランダムな正の整数を生成します。式には、0 ~ 2,147,483,647 の任意の値を指定できます。この式 mod 最初の式は、分単位で有効なオフセットを提供します。
epxressionDATEDIFF(MINUTE, 0, StartDateTime)
は、開始日時と参照日時の間の合計分数を表します。0
これは、の短縮形です'1900-01-01 00:00:00.000'
。基準日時の値は関係ありませんが、式全体で同じ基準日が使用されていることが重要です。これをオフセットに追加して、参照日時間の合計分数を取得します。
カプセル化された DATEADD 関数は、前の式によって生成された分数を参照日時に追加することにより、これを日時値に変換します。
これに使用できますRAND
:
select cast(cast(RAND()*100000 as int) as datetime)
ここから
Sql-Fiddle は非常に良さそうです: http://sqlfiddle.com/#!3/b9e44/2/0