14 Stimmen

Was ist der beste Weg, um die letzten 24 Stunden Ergebnisse in T-SQL zu erhalten?

Ich arbeite an der Erstellung eines Diagramms für meinen Kunden und er möchte die Gesamtzahl der Kunden über einen Zeitraum von 24 Stunden, 3 Tagen, 1 Woche, 1 Monat usw. ermitteln. Ich bin ehrlich gesagt nicht der beste mit SQL, so dass die Erstellung dieser Abfragen sind nicht meine Stärke.

Um die Kunden über 24 Stunden zu erreichen, bin ich auf zwei "Wo"-Anweisungen gestoßen, die möglicherweise funktionieren, aber ich bin nicht sicher, welche die beste ist.

Erste Version:

WHERE DATEDIFF(hh,CreatedDate,GETDATE())>24

Zweite Version:

WHERE CreatedDate >= DATEADD(HH, -24, GETDATE())

Die erste Version erzeugt 21 Zeilen und die zweite 17 Zeilen (natürlich aus demselben Datensatz), so dass offensichtlich eine Version genauer ist als die andere. Ich tendiere zu der ersten, aber ich würde gerne Ihre Meinung hören... bitte.

Danke, Andrew

11voto

Florian Reischl Punkte 3738

Vermeiden Sie die erste Version. Erstens, weil sie die Indexnutzung deaktiviert. Das zweite (funktionale) Problem mit der ersten Version ist, DATEDIFF(HOUR...) gibt alle Werte zurück, die weniger als 25 Stunden betragen. Versuchen Sie dies zur Verdeutlichung:

SELECT DATEDIFF(HOUR, '2010-07-19 00:00:00', '2010-07-20 00:59:59.99')

11voto

ErikE Punkte 46297

Die erste Version ist nicht korrekt.

WHERE DateDiff(hh, CreatedDate, GETDATE()) > 24

Dies ergibt Werte zwischen 23.0001 Stunden und 24.9999 Stunden, da Sie die "überschrittenen Grenzen" zählen und nicht einen tatsächlichen 24-Stunden-Zeitraum. Bedenken Sie, dass von 1:59:59 zu 2:00:00 ist nur eine Sekunde, aber DateDiff nach Stunden wird 1 Stunde zurückgegeben. Ähnlich, 1:00:00 zu 2:59:59 beträgt fast 2 Stunden, aber DateDiff nach Stunden ergibt die gleiche 1 Stunde.

Die zweite Version ist korrekt.

WHERE CreatedDate >= DateAdd(hh, -24, GETDATE())

Subtrahiert man 24 Stunden vom aktuellen Datum, erhält man eine Zeit, die auf die Millisekunde genau 24,0 Stunden zurückliegt. Es werden also 24 Stunden an Daten zurückgegeben.

Außerdem wäre die erste Version schlecht, selbst wenn es das wäre, was Sie wollten, weil die Engine Datumsberechnungen für jede einzelne Zeile in der gesamten Tabelle durchführen müsste, was jeden potenziellen Index nutzlos macht und einen Haufen unnötiger CPU verbraucht. Führen Sie stattdessen die Berechnungen auf der dem Spaltennamen gegenüberliegenden Seite des Ausdrucks durch. Um die Logik Ihres ersten Ausdrucks ohne Leistungseinbußen zu duplizieren, würde das folgendermaßen aussehen:

WHERE CreateDate >= DateAdd(hh, DateDiff(hh, 0, GETDATE()) - 24, 0)

Beispiel:

  • GetDate() = '20100720 17:52'
  • DateDiff(hh, 0, '20100720 17:52') = 969065
  • DateAdd(hh, 969065 - 24, 0) = '20100719 17:00'

und zu beweisen, dass dies dasselbe ist wie Ihr erster Ausdruck:

  • DateDiff(hh, '20100719 17:00', '20100720 17:52') = 24

0voto

crosan Punkte 476

Vielleicht diese für jede Ihrer Where-Klauseln?

WHERE CreatedDate < GETDATE() AND CreatedDate >= DATEADD(hh, -24, GETDATE)

WHERE CreatedDate < GETDATE() AND CreatedDate >= DATEADD(day, -3, GETDATE)

WHERE CreatedDate < GETDATE() AND CreatedDate >= DATEADD(wk, -1, GETDATE)

WHERE CreatedDate < GETDATE() AND CreatedDate >= DATEADD(mm, -1, GETDATE)

Und wie Flo über Indizes erwähnt hat, stellen Sie einfach sicher, dass Sie Ihre CreatedDate-Spalte indizieren.

CodeJaeger.com

CodeJaeger ist eine Gemeinschaft für Programmierer, die täglich Hilfe erhalten..
Wir haben viele Inhalte, und Sie können auch Ihre eigenen Fragen stellen oder die Fragen anderer Leute lösen.

Powered by:

X