2

2 つの日付の間の値をDATETIME持つ TSQLの列を含むテーブルを更新する最も簡単な方法は何ですか?RANDOM

ORDER BY DATEそれに関連するさまざまな投稿を目にしますが、更新後にランダム値が実際に連続しています。

4

2 に答える 2

10

仮定

最初に、日時の範囲を定義する開始日時列と終了日時列を持つテーブルを含むデータベースがあるとします。

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 関数は、前の式によって生成された分数を参照日時に追加することにより、これを日時値に変換します。

于 2012-07-09T00:47:30.533 に答える
8

これに使用できますRAND

select cast(cast(RAND()*100000 as int) as datetime)

ここから

Sql-Fiddle は非常に良さそうです: http://sqlfiddle.com/#!3/b9e44/2/0

于 2012-07-08T22:32:18.467 に答える