Das Speichern der Daten in einer einzelnen Spalte ist die bevorzugte Methode, da sie untrennbar miteinander verbunden sind. Ein Zeitpunkt ist eine einzelne Information, nicht zwei.
Eine übliche Methode zum Speichern von Datums- / Zeitdaten, die von vielen Produkten "hinter den Kulissen" verwendet werden, besteht darin, sie in einen Dezimalwert umzuwandeln, wobei "Datum" der ganzzahlige Teil des Dezimalwerts und "Zeit" der Bruchteil ist Wert. So wird zwischen 1900-01-01 00:00:00 als 0,0 und dem 20. September 2016 zwischen 9:34:00 als 42631.39861 gespeichert. 42631 ist die Anzahl der Tage seit dem 01.01.1900. .39861 ist die Zeit, die seit Mitternacht vergangen ist. Verwenden Sie dazu nicht direkt einen Dezimaltyp, sondern einen expliziten Datums- / Zeittyp. Mein Punkt hier ist nur eine Illustration.
Wenn Sie die Daten in zwei separaten Spalten speichern, müssen Sie beide Spaltenwerte immer dann kombinieren, wenn Sie sehen möchten, ob ein bestimmter Zeitpunkt früher oder später als der gespeicherte Wert liegt.
Wenn Sie die Werte separat speichern, werden Sie ausnahmslos auf "Bugs" stoßen, die schwer zu erkennen sind. Nehmen wir zum Beispiel folgendes:
IF OBJECT_ID('tempdb..#DT') IS NOT NULL
DROP TABLE #DT;
CREATE TABLE #DT
(
dt_value DATETIME NOT NULL
, d_value DATE NOT NULL
, t_value TIME(0) NOT NULL
);
DECLARE @d DATETIME = '2016-09-20 09:34:00';
INSERT INTO #DT (dt_value, d_value, t_value)
SELECT @d, CONVERT(DATE, @d), CONVERT(TIME(0), @d);
SET @d = '2016-09-20 11:34:00';
INSERT INTO #DT (dt_value, d_value, t_value)
SELECT @d, CONVERT(DATE, @d), CONVERT(TIME(0), @d);
/* show all rows with a date after 2016-07-01 11:00 am */
SELECT *
FROM #DT dt
WHERE dt.dt_value >= '2016-07-01 11:00:00';
/* show all rows with a date after 2016-07-01 11:00 am */
SELECT *
FROM #DT dt
WHERE dt.d_value >= CONVERT(DATE, '2016-07-01')
AND dt.t_value >= CONVERT(TIME(0), '11:00:00');
Im obigen Code erstellen wir eine Testtabelle, füllen sie mit zwei Werten und führen dann eine einfache Abfrage für diese Daten durch. Die erste SELECT
gibt beide Zeilen zurück, die zweite SELECT
gibt jedoch nur eine einzelne Zeile zurück, was möglicherweise nicht das gewünschte Ergebnis ist:
Die richtige Methode zum Filtern eines Datums- / Zeitbereichs, in dem sich die Werte in separaten Spalten befinden, wie von @ypercube in Kommentaren hervorgehoben, lautet:
WHERE dt.d_value > CONVERT(DATE, '2016-07-01') /* note there is no time component here */
OR (
dt.d_value = CONVERT(DATE, '2016-07-01')
AND dt.t_value >= CONVERT(TIME(0), '11:00:00')
)
Wenn Sie die Zeitkomponente zu Analysezwecken getrennt benötigen , können Sie eine berechnete, dauerhafte Spalte für den Zeitanteil des Werts hinzufügen:
ALTER TABLE #DT
ADD dt_value_time AS CONVERT(TIME(0), dt_value) PERSISTED;
SELECT *
FROM #dt;
Die persistierte Spalte könnte dann indiziert werden, um schnelle Sortierungen usw. nach Tageszeit zu ermöglichen.
Wenn Sie das Datum und die Uhrzeit für Anzeigezwecke in zwei Felder aufteilen möchten, sollten Sie beachten, dass die Formatierung auf dem Client und nicht auf dem Server erfolgen sollte.