So aktualisieren Sie Zeilen mit einem zufälligen Datum

69

Ich habe eine einfache SQL-Tabelle mit einer DateTime-Spalte. Ich möchte alle Zeilen (> 100000 Zeilen) mit einem zufälligen Datum aktualisieren. Gibt es eine einfache Möglichkeit, eine SQL-Abfrage durchzuführen?

Martin
quelle

Antworten:

90

Verwenden Sie diese Option, um eine kleine Datenzeit zwischen dem 01. Januar 1900 und dem 06. Juni 2079 zu generieren (nicht aktiviert, SQL nicht installiert).

DATEADD(day, (ABS(CHECKSUM(NEWID())) % 65530), 0)

NEWID ist besser als der Versuch, RAND zu verwenden: RAND generiert keine unterschiedlichen Wertezeilen in einem einzelnen SELECT oder UPDATE (auch nicht in SQL 2000, falls sich das Verhalten geändert hat).

Edit: so

UPDATE
  table
SET
  datetimecol = DATEADD(day, (ABS(CHECKSUM(NEWID())) % 65530), 0)

Bearbeiten: 65535 in 65530 geändert und ABS hinzugefügt, um einen Überlauf an der oberen Bereichsgrenze zu vermeiden

gbn
quelle
Klug! Arbeitete für mich unter SQL Server 2000. create table #test (d datetime); in #test Werte einfügen (null); in #test Werte einfügen (null); in #test Werte einfügen (null); Update #test SET d = DATEADD (Tag, (ABS (CHECKSUM (NEWID ()))% 65530), 0); Wählen Sie * aus #test; drop table #test;
Patrick McElhaney
Bitte, warum ist die Nummer 65530? Wie zählt man es?
Amelina
@Amelina "änderte 65535 zu 65530 und fügte ABS hinzu, um einen Überlauf an der oberen Grenze des Bereichs zu vermeiden"
gbn
Ja, ich habe es verstanden. Ich habe nicht verstanden, wie ich es für einen anderen Bereich berechnen soll. Ist 65530 Sekunden, Millisekunden oder?
Amelina
1
@Amelina das sind die maximale Anzahl von Tagen. Wenn Sie dies tun, werden select dateadd(day,65530,0)Sie sehen, dass es am 2079-06-01 endet.
Sander
64

Ich werde die Antworten unten ergänzen,

SELECT DATEADD(DAY, ABS(CHECKSUM(NEWID()) % 3650), '2000-01-01')
FROM your_table

Dies generiert Daten ab dem 01.01.2000, und Sie können die Anzahl der Tage im Modulwert ändern. Ich habe 3650 (ca. 10 Jahre) angegeben. Dieser Ansatz läuft nicht über.

Wenn Sie aktualisieren möchten, dann

UPDATE your_table
SET your_date_field = DATEADD(DAY, ABS(CHECKSUM(NEWID()) % 3650), '2000-01-01')
WHERE your_conditions
Jhonny D. Cano -Leftware-
quelle
2
Ja, ich hatte einen Fehler in meinem. CHECKSUM generiert vorzeichenbehaftete 32-Bit-Ganzzahlen, also habe ich ABS
gbn
40

Diese Frage scheint ziemlich alt zu sein, aber meine Antwort könnte für andere nützlich sein.

      Update table
      SET Time= DateAdd(d, ROUND(DateDiff(d, '2010-01-01', '2013-12-31') * RAND(CHECKSUM(NEWID())), 0),
      DATEADD(second,CHECKSUM(NEWID())%48000, '2010-01-01'))

Dies erzeugt eine zufällige Datums- / Uhrzeitangabe zwischen einem bestimmten Bereich.

Pieter_Daems
quelle
myeah. nett. Liebe es.
Ash
Gute Lösung mit dem RAND(CHECKSUM(NEWID()))- Ich habe eine RANK() OVERBestellung an einem Datum durchgeführt, aber aufgrund von Dateneingabefehlern (außerhalb meiner Kontrolle) gab es zwei Zeilen, die genau das gleiche Datum hatten und anschließend den gleichen Rang erhielten, wenn die Zeilen ein haben sollten Rang 1 bzw. 2.
Puiu
8

Ich habe Jhonnys Antwort oben angepasst, um Daten aus 10 Jahren in der Vergangenheit zu erhalten:

SELECT dateadd(day, (abs(CHECKSUM(newid())) % 3650) * -1, getdate())

Beachten Sie, dass dies nur SQLServer ist.

Christopher Marshall
quelle
5

Der folgende Code füllt die Spalte StartDate der FiscalYear-Tabelle mit zufälligen Daten zwischen zwei angegebenen Daten:

-- First, let's declare the date range.
DECLARE @date_from DATETIME;
DECLARE @date_to DATETIME;

-- Set the start and date dates. In this case, we are using
-- the month of october, 2006.
SET @date_from = '1985-10-14';
SET @date_to = '2009-04-27';

UPDATE FiscalYear SET StartDate =  
(
    -- Remember, we want to add a random number to the
    -- start date. In SQL we can add days (as integers)
    -- to a date to increase the actually date/time
    -- object value.
    @date_from +
    (
        -- This will force our random number to be >= 0.
        ABS
        (
            -- This will give us a HUGE random number that
            -- might be negative or positive.
            CAST(CAST(NewID() AS BINARY(8)) AS INT)
        )

        -- Our random number might be HUGE. We can't have
        -- exceed the date range that we are given.
        -- Therefore, we have to take the modulus of the
        -- date range difference. This will give us between
        -- zero and one less than the date range.
        %

        -- To get the number of days in the date range, we
        -- can simply substrate the start date from the
        -- end date. At this point though, we have to cast
        -- to INT as SQL will not make any automatic
        -- conversions for us.
        CAST((@date_to - @date_from) AS INT)
    )
)
CSharper
quelle
1
Dieser generiert für jede Zeile ein anderes Datum.
CSharper
Warum nicht DATEADD und DATEDIFF verwenden?
Gbn
5

Ich habe dies verwendet, um ein Geburtsdatum zwischen 1940 und 1985 für alle meine Testdaten festzulegen

SET [Birth Date] = DATEADD(day, (ABS(CHECKSUM(NEWID())) % 16250), '1940-1-1 00:00:00.001')
Paul Cunningham
quelle
2

Ich suchte nach einer ähnlichen Frage, die auch eine zufällige Zeit erzeugte, und fand dieses Skript. Dachte, es könnte hier nützlich sein:

DECLARE @DateFrom DATETime = '2001-01-01'
DECLARE @DateTo DATeTime = '2013-11-30'
DECLARE @DaysRandom Int= 0
DECLARE @MillisRandom Int=0

--get random number of days

select @DaysRandom= DATEDIFF(day,@DateFrom,@DateTo)
SELECT @DaysRandom = ROUND(((@DaysRandom -1) * RAND()), 0)

--get random millis
SELECT @MillisRandom = ROUND(((99999999) * RAND()), 0)

SELECT @DateTo = DATEADD(day, @DaysRandom, @DateFrom)
SELECT @DateTo = DATEADD(MILLISECOND, @MillisRandom, @DateTo)
SELECT @DateTo

Ich habe es von hier bekommen: http://crodrigues.com/sql-server-generate-random-datetime-within-a-range/

aug
quelle
1

Sie können versuchen, eine Zufallszahl (positiv oder negativ) zu erhalten und diese Zahl dann einem Datum (möglicherweise dem Systemdatum) hinzuzufügen.

Zum Beispiel (Ich habe momentan keinen Zugriff auf SQL Server, daher konnte ich die Syntax nicht überprüfen.)

DATEADD(day, DATEDIFF(day, 0, GETDATE()) - 1 - FLOOR(RAND(CAST(NEWID() AS binary(4))) * 365.25 * 90), 0)
Nordpol
quelle
In SQL Server 2019 (10 Jahre später) funktioniert dies für mehrere Zeilen. SELECT DATEADD(DAY, DATEDIFF(DAY, 0, GETDATE()) - 1 - FLOOR(RAND(CAST(NEWID() AS BINARY(4))) * 365.25 * 90), 0), ROW_NUMBER() OVER (ORDER BY (SELECT NULL)) FROM (VALUES(0),(0),(0),(0),(0),(0),(0),(0),(0),(0)) a(n)
Nielsvh
0

Mit dem folgenden Code können Sie eine zufällige Ganzzahl zwischen @Min (1) und @Max (365) erhalten. Mit der Funktion dateadd können Sie dann zufällige Daten im letzten Jahr erstellen.

CREATE VIEW vRandNumber
AS
SELECT RAND() as RandNumber
GO

CREATE FUNCTION RandNumber(@Min int, @Max int)
RETURNS int
AS
 BEGIN
 RETURN round(@Min + (select RandNumber from vRandNumber) * (@Max-@Min),0)
 END
GO

Update table1
set theDate = dateadd(d,0-dbo.RandNumber(1,365),getdate())
Jon Masters
quelle
Das udf kann RAND pro Zeile unterschiedlich angeben. Ich werde es morgen versuchen
gbn
0

Ich habe mehrere Antworten für mich kombiniert, ich denke, es funktioniert für Sie. Es dauerte 40 Sekunden, bis ich dies für 140.000 Zeilen ausgeführt hatte. i5, 1333 MHz, Standard-Laptop-Festplatte

 DECLARE @rank INT = 0;

WHILE @rank < yourmaxrow --(you can use Select count (*) from your table name as well)
BEGIN
   DECLARE @FromDate DATETIME = DATEADD(DAY, -720, GETDATE()) -- 2 years back
   DECLARE @ToDate   DATETIME = DATEADD(DAY, -1, GETDATE()) -- until yesterday

   DECLARE @Seconds INT = DATEDIFF(SECOND, @FromDate, @ToDate)
   DECLARE @Random INT = ROUND(((@Seconds-1) * RAND()), 0)
   DECLARE @Milliseconds INT = ROUND((999 * RAND()), 0)

update yourtablename
Set yourdatetiemcolumnname = DATEADD(MILLISECOND, @Milliseconds, DATEADD(SECOND, @Random, @FromDate))
WHERE Id = @rank
   SET @rank = @rank + 1;       
END;
MEO
quelle