So kombinieren Sie Datum aus einem Feld mit Uhrzeit aus einem anderen Feld - MS SQL Server


198

In einem Auszug, mit dem ich mich befasse, habe ich 2 datetimeSpalten. In einer Spalte werden die Daten und in einer anderen die angezeigten Zeiten gespeichert.

Wie kann ich die Tabelle abfragen, um diese beiden Felder in einer Spalte des Typs zu kombinieren datetime?

Termine

2009-03-12 00:00:00.000
2009-03-26 00:00:00.000
2009-03-26 00:00:00.000

Mal

1899-12-30 12:30:00.000
1899-12-30 10:00:00.000
1899-12-30 10:00:00.000

Antworten:


252

Sie können einfach die beiden hinzufügen.

  • wenn die Time partIhrer DateSpalte immer Null ist
  • und die Date partIhrer TimeSpalte ist auch immer Null (Basisdatum: 1. Januar 1900)

Wenn Sie sie hinzufügen, erhalten Sie das richtige Ergebnis.

SELECT Combined = MyDate + MyTime FROM MyTable

Begründung (ein großes Lob an ErikE / dnolan)

Dies funktioniert aufgrund der Art und Weise, wie das Datum als zwei 4-Bytes gespeichert wird, Integerswobei das linke 4-Byte das dateund das rechte 4-Byte das ist time. Es ist wie zu tun$0001 0000 + $0000 0001 = $0001 0001

Bearbeiten Sie neue SQL Server 2008-Typen

Dateund Timesind Typen eingeführt in SQL Server 2008. Wenn Sie darauf bestehen, hinzuzufügen, können Sie verwendenCombined = CAST(MyDate AS DATETIME) + CAST(MyTime AS DATETIME)

Edit2 bezüglich Genauigkeitsverlust in SQL Server 2008 und höher (ein großes Lob an Martin Smith)

Schauen Sie sich an, wie Datum und Uhrzeit in SQL Server mit datetime2 kombiniert werden. um Präzisionsverluste mit SQL Server 2008 und höher zu vermeiden.


2
@ Jon, es ist wahr, solange das Zeitelement der Datumsspalte und das Datumselement der Zeitspalte beide Null sind.
LukeH

1
Sie erleben höchstwahrscheinlich, was hier beschrieben wird groups.google.be/group/… borland * + author% 3A teamb * # 1ab62659d8be3135
Lieven Keersmaekers

2
Das "Null" -Datum in SQL Server ist 1900-01-01, nein?
Andriy M

1
Als ich das versuchte, musste ich den Wert 'time' nicht in datetime umwandeln. Mit anderen Worten, Sie können tun: Datum / Uhrzeit
Sam

1
@ dnolan-Daten in SQL Server werden NICHT als gespeichert float. Wo um alles in der Welt hast du das gelernt? Sie werden als Ganzzahlen gespeichert : Der Datumsanteil ist die Anzahl der Tage seit einem Ankerdatum, und der Zeitanteil ist die Anzahl der "Ticks" seit Mitternacht, wobei Ticks als 1/300 s für datetimeund genauer für timeund definiert sind datetime2.
ErikE

129

Wenn das Zeitelement Ihrer Datumsspalte und das Datumselement Ihrer Zeitspalte beide Null sind, ist Lievens Antwort genau das, was Sie brauchen. Wenn Sie nicht garantieren können, dass dies immer der Fall sein wird, wird es etwas komplizierter:

SELECT DATEADD(day, 0, DATEDIFF(day, 0, your_date_column)) +
    DATEADD(day, 0 - DATEDIFF(day, 0, your_time_column), your_time_column)
FROM your_table

Danke für die Antwort Luke. Glücklicherweise kann ich in diesem Fall garantieren, dass andere Elemente immer Null sind. Ich denke, die 2 Felder können sogar 1 auf der anderen Seite des Codes von Drittanbietern sein, der den Extrakt für uns erstellt.
Jon Winstanley

6
Ich hatte das gleiche Problem wie das OP, außer dass ich weiß, dass die nicht benötigten Teile niemals Null sind. Dies war daher unermesslich nützlich, wenn ich Sie zweimal abstimmen könnte, würde ich!

Das hat mich gerettet! Ich habe beide in Zeichen konvertiert und dann konzertiert und dann zurück zu DATETIME, aber dann konnte ich es nicht indizieren, weil SQL sagte, es sei nicht deterministisch. Dies ist anscheinend deterministisch !!! DANKE !!! SIE !!!
Eidylon

4
Ihre SQL Server 2008-Version funktioniert nicht. The data types datetime and time are incompatible in the add operator.
Martin Smith

@ Martin: Ich habe die kaputte SQL2008-Version entfernt.
LukeH

26

Dies ist eine alternative Lösung ohne Zeichenkonvertierung:

DATEADD(ms, DATEDIFF(ms, '00:00:00', [Time]), CONVERT(DATETIME, [Date]))

Auf diese Weise erhalten Sie nur eine Millisekundengenauigkeit, aber das wäre normalerweise in Ordnung. Ich habe dies in SQL Server 2008 getestet.


14

Das hat bei mir funktioniert

CAST(Tbl.date as DATETIME) + CAST(Tbl.TimeFrom AS TIME)

(unter SQL 2008 R2)


1
Funktionierte hervorragend in SQL Server 2008.
Tobias

7
Ich erhalte Die Datentypen datetime und time sind im Operator add nicht kompatibel. Fehler auf SQL Server 2012
Devin Prejean

4
SQL 2012 Die Datentypen datetime und time sind im Add-Operator nicht
kompatibel

3
Dies funktioniert in SQL Server 2012 und höher nicht mehr (Änderung). Siehe hier für Details: social.msdn.microsoft.com/forums/azure/en-US/…
Heinzi

10

Wenn Sie SQL Server 2008 nicht verwenden (dh Sie haben nur einen DateTime-Datentyp), können Sie die folgende (zugegebenermaßen grobe und fertige) TSQL verwenden, um das zu erreichen, was Sie möchten:

DECLARE @DateOnly AS datetime
DECLARE @TimeOnly AS datetime 

SET @DateOnly = '07 aug 2009 00:00:00'
SET @TimeOnly = '01 jan 1899 10:11:23'


-- Gives Date Only.
SELECT DATEADD(dd, 0, DATEDIFF(dd, 0, @DateOnly))

-- Gives Time Only.
SELECT DATEADD(Day, -DATEDIFF(Day, 0, @TimeOnly), @TimeOnly)

-- Concatenates Date and Time parts.
SELECT
CAST(
    DATEADD(dd, 0, DATEDIFF(dd, 0, @DateOnly)) + ' ' +
    DATEADD(Day, -DATEDIFF(Day, 0, @TimeOnly), @TimeOnly)           
as datetime)

Es ist rau und fertig, aber es funktioniert!


9
  1. Wenn beide Felder datetime sind, funktioniert das einfache Hinzufügen dieser Felder.

    z.B:

    Declare @d datetime, @t datetime
    set @d = '2009-03-12 00:00:00.000';
    set @t = '1899-12-30 12:30:00.000';
    select @d + @t
  2. Wenn Sie den Datentyp Datum und Uhrzeit verwendet haben, wandeln Sie die Uhrzeit einfach in Datum und Uhrzeit um

    z.B:

    Declare @d date, @t time
    set @d = '2009-03-12';
    set @t = '12:30:00.000';
    select @d + cast(@t as datetime)

3

Konvertieren Sie das erste in einem Datum / Uhrzeit-Feld gespeicherte Datum in eine Zeichenfolge, konvertieren Sie dann die in einem Datum / Uhrzeit-Feld gespeicherte Zeit in eine Zeichenfolge, hängen Sie die beiden an und konvertieren Sie sie wieder in ein Datum / Uhrzeit-Feld, wobei alle bekannten Konvertierungsformate verwendet werden.

Convert(datetime, Convert(char(10), MYDATETIMEFIELD, 103) + ' ' + Convert(char(8), MYTIMEFIELD, 108), 103) 

3
Die Konvertierung in einen String ist langsamer als dateadd. stackoverflow.com/questions/2775/…
ErikE

2

Ich hatte viele Fehler wie oben angegeben, also habe ich es so gemacht

try_parse(concat(convert(date,Arrival_date),' ',arrival_time) as datetime) AS ArrivalDateTime

Es hat bei mir funktioniert.


2

Konvertieren Sie beide Felder in DATETIME:

SELECT CAST(@DateField as DATETIME) + CAST(@TimeField AS DATETIME)

und wenn Sie verwenden, Getdate()verwenden Sie dies zuerst:

DECLARE @FechaActual DATETIME = CONVERT(DATE, GETDATE());
SELECT CAST(@FechaActual as DATETIME) + CAST(@HoraInicioTurno AS DATETIME)

1
DECLARE @Dates table ([Date] datetime);
DECLARE @Times table ([Time] datetime);

INSERT INTO @Dates VALUES('2009-03-12 00:00:00.000');
INSERT INTO @Dates VALUES('2009-03-26 00:00:00.000');
INSERT INTO @Dates VALUES('2009-03-30 00:00:00.000');

INSERT INTO @Times VALUES('1899-12-30 12:30:00.000');
INSERT INTO @Times VALUES('1899-12-30 10:00:00.000');
INSERT INTO @Times VALUES('1899-12-30 10:00:00.000');

WITH Dates (ID, [Date])
AS (
    SELECT ROW_NUMBER() OVER (ORDER BY [Date]), [Date] FROM @Dates
), Times (ID, [Time])
AS (
    SELECT ROW_NUMBER() OVER (ORDER BY [Time]), [Time] FROM @Times
)
SELECT Dates.[Date] + Times.[Time] FROM Dates
    JOIN Times ON Times.ID = Dates.ID

Drucke:

2009-03-12 10:00:00.000
2009-03-26 10:00:00.000
2009-03-30 12:30:00.000

1
SELECT CAST(your_date_column AS date) + CAST(your_time_column AS datetime) FROM your_table

Klappt wunderbar


0

SELECT CAST (CAST (@DateField als Datum) als DateTime) + CAST (CAST (@TimeField als Zeit) als DateTime)


0

Eine andere Möglichkeit besteht darin, zu verwenden CONCATund CASTsich dessen bewusst zu sein, dass Sie es verwenden müssen DATETIME2(x), damit es funktioniert. Sie können xalles einstellen , was 0-7 7bedeutet, dass kein Genauigkeitsverlust vorliegt.

DECLARE @date date = '2018-03-12'
DECLARE @time time = '07:00:00.0000000'
SELECT CAST(CONCAT(@date, ' ', @time) AS DATETIME2(7))

Kehrt zurück 2018-03-12 07:00:00.0000000

Getestet auf SQL Server 14


-1

Um das Datum aus einer Datums- / Uhrzeitspalte und die Uhrzeit aus einer anderen Datums- / Uhrzeitspalte zu kombinieren, ist dies die beste und schnellste Lösung für Sie:

select cast(cast(DateColumn as date) as datetime) + cast(TimeColumn as datetime) from YourTable

Ergebnisse im Fehler "Die Datentypen datetime und time sind im Operator add nicht kompatibel."
Oskar Berggren

-1

Ich hatte eine ähnliche Situation, in der ich Datums- und Zeitfelder mit DateTime-Feldern zusammenführen musste. Keine der oben genannten Lösungen funktioniert, insbesondere das Hinzufügen von zwei Feldern als Datentyp für das Hinzufügen dieser beiden Felder ist nicht identisch.

Ich habe die folgende Lösung erstellt, bei der ich dem Datum einen Stunden- und einen Minutenteil hinzugefügt habe. Das hat bei mir wunderbar funktioniert. Bitte probieren Sie es aus und lassen Sie mich wissen, wenn Sie auf Probleme stoßen.

; mit tbl als (wählen Sie StatusTime = '12 / 30/1899 17:17:00 PM ', StatusDate =' 24.07.2019 00:00:00 ') wählen Sie DATEADD (MI, DATEPART (MINUTE, CAST (tbl .StatusTime AS TIME)), DATEADD (HH, DATEPART (STUNDE, CAST (tbl.StatusTime AS TIME)), CAST (tbl.StatusDate as DATETIME))) von tbl

Ergebnis: 2019-07-24 17: 17: 00.000

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.