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?

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


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

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.


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.


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)
    )
)

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')

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/


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)

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())

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;
Durch die Nutzung unserer Website bestätigen Sie, dass Sie unsere Cookie-Richtlinie und Datenschutzrichtlinie gelesen und verstanden haben.
Licensed under cc by-sa 3.0 with attribution required.