2017-05-11 2 views
0

Ich versuche, mehrere Änderungen an einem zufälligen Datum zu machen, um eine vollständige zufällige Datetime innerhalb einer Reihe von Daten (3 Monate zurück, 3 Monate nach vorne) aber Einstellung der Stunden/Minuten/Sekunden/Millisekunden zu 0.Mehrere DATEADD-Funktionen in einer Abfrage - TSQL

Ich mache das, also kann ich dann eine zufällige Menge an Zeit hinzufügen, um Aktivitätsanfangs- und Endzeiten zu schaffen, die immer innerhalb der Büroarbeitsstunden passen. Das folgende Skript legt eine Variable für die Startzeit der Aktivität fest und führt dann 5 separate Änderungen an dieser Variablen durch, um das Zeitelement auf Null zu setzen.

Gibt es eine einfachere Möglichkeit, mehrere DATEADD-Bearbeitungen auszuführen, scheint es klobig zu sein!

DECLARE @STARTTIME DATETIME 
DECLARE @ENDTIME DATETIME 

SET @STARTTIME = (SELECT DATEADD(DAY,ABS(CHECKSUM(NEWID()) % 180), (select dateadd(dd, -90, getdate())))) 

SET @STARTTIME = (SELECT DATEADD(HH, - (SELECT DATEPART(HH,@STARTTIME)),@STARTTIME)) 
SET @STARTTIME = (SELECT DATEADD(MI, - (SELECT DATEPART(MI,@STARTTIME)),@STARTTIME)) 
SET @STARTTIME = (SELECT DATEADD(SS, - (SELECT DATEPART(SS,@STARTTIME)),@STARTTIME)) 
SET @STARTTIME = (SELECT DATEADD(MS, - (SELECT DATEPART(MS,@STARTTIME)),@STARTTIME)) 
SET @STARTTIME = (SELECT DATEADD(hh,(SELECT FLOOR(RAND()*(15-08)+08)), @STARTTIME)) 
SET @ENDTIME = (SELECT DATEADD(hh,(SELECT FLOOR(RAND()*(3-1)+1)), @STARTTIME)) 

SELECT 
@STARTTIME AS 'STARTTIME', 
@ENDTIME AS 'ENDTIME' 

Results 
STARTIME 2017-04-02 13:00:00.000 
ENDTIME 2017-04-02 15:00:00.000 
+2

N.B. In einer SET-Anweisung brauchen Sie die SELECTs nicht unbedingt vor jedem Aufruf einer Funktion (z. B. DATEADD). Wird den Code lesbarer machen. Ich weiß nicht über klobig, zumindest ist Ihr Code ziemlich klar. Sie könnten alle DateAdd-Anweisungen auf jede andere Zeile ketten, aber das würde nur eine schreckliche unlesbare Unordnung schaffen. – ADyson

+0

Sehr geschätzt, und danke für den Tipp! – KEW

Antwort

2

Es gibt keine Notwendigkeit newid() in T-SQL-Code zu verwenden. Es wird nur innerhalb einer Abfrage benötigt, um mehrere Zufallszahlen zu generieren.

So:

set @starttime = cast(datedd(day, floor(rand() * 180 - 90), getdate()) as date); 

set @starttime = dateadd(hour, floor(rand()*(15-08)+08), @starttime); 
set @enddtime = dateadd(hour, floor(rand()*(3-1)+1), @starttime); 

Hinweise:

  • Dies verwendet cast(. . . as date) die Zeitkomponente des Datums zu entfernen.
  • Es müssen keine verschachtelten select Anweisungen eingegeben werden.
  • Für T-SQL-Code können Sie rand() statt der newid() Work-around (das in einer einzelnen Abfrage benötigt wird, um mehrere zufällige Werte zu generieren) verwenden.
  • Verwenden Sie keine Datumsteilabkürzungen wie "hh". Einfach den Datumsteil buchstabieren. Der Code ist viel einfacher zu schreiben und zu pflegen.
+0

Das ist ein toller Rat, danke. Ihre Lösung war auch viel einfacher als ich es gemacht habe! Ich habe die CAST-Zeile leicht bearbeitet, damit sie funktioniert: set @starttime = cast (dateadd (Tag, Floor (rand() * 180 - 90), getdate()) als Datum); – KEW

2

Sie wandeln es in eine Art Datum Datensatz würde die Zeit Teil auf 00: 00: 000

DECLARE @STARTTIME DATETIME 
DECLARE @ENDTIME DATETIME 

SET @STARTTIME = cast((SELECT DATEADD(DAY,ABS(CHECKSUM(NEWID()) % 180), (select dateadd(dd, -90, getdate())))) as date) 

SET @STARTTIME = (SELECT DATEADD(hh,(SELECT FLOOR(RAND()*(15-08)+08)), @STARTTIME)) 
SET @ENDTIME = (SELECT DATEADD(hh,(SELECT FLOOR(RAND()*(3-1)+1)), @STARTTIME)) 

SELECT 
@STARTTIME AS 'STARTTIME', 
@ENDTIME AS 'ENDTIME' 
+0

Danke dafür, es hat genau wie gefragt und mein Problem gelöst. Entschuldigungen, dass ich die Lösung für den Beitrag von Gordon gegeben habe, war eine umfassendere Antwort für zukünftige Benutzer. Danke noch einmal! – KEW