Come combinare la data di un campo con l'ora di un altro campo: MS SQL Server


198

In un estratto di cui mi occupo, ho 2 datetimecolonne. Una colonna memorizza le date e un'altra le ore come mostrato.

Come posso eseguire una query sulla tabella per combinare questi due campi in 1 colonna di tipo datetime?

Date

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

Volte

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

Risposte:


253

Puoi semplicemente aggiungere i due.

  • se l' Time partdella vostra Datecolonna è sempre zero
  • e la Date partdella vostra Timecolonna è anche sempre zero (data di base: 1 gennaio 1900)

Aggiungendoli si ottiene il risultato corretto.

SELECT Combined = MyDate + MyTime FROM MyTable

Razionale (complimenti a ErikE / dnolan)

Funziona in questo modo a causa del modo in cui la data è memorizzata come due 4 byte Integerscon i 4 byte a sinistra che sono i 4 e i byte a datedestra che sono i time. È come fare$0001 0000 + $0000 0001 = $0001 0001

Modifica per quanto riguarda i nuovi tipi di SQL Server 2008

Datee Timesono i tipi introdotti in SQL Server 2008. Se insisti nell'aggiungere, puoi usareCombined = CAST(MyDate AS DATETIME) + CAST(MyTime AS DATETIME)

Modifica2 per quanto riguarda la perdita di precisione in SQL Server 2008 e versioni successive (complimenti a Martin Smith)

Dai un'occhiata a Come combinare data e ora a datetime2 in SQL Server? per prevenire la perdita di precisione utilizzando SQL Server 2008 e versioni successive.


2
@Jon, È vero fintanto che l'elemento time della colonna date e l'elemento date della colonna time sono entrambi zero.
Luca,

1
Molto probabilmente stai vivendo ciò che è descritto qui groups.google.be/group/… borland * + author% 3A teamb * # 1ab62659d8be3135
Lieven Keersmaekers

2
La data "zero" in SQL Server è 1900-01-01no?
Andriy M,

1
Quando ho provato questo, non avevo bisogno di trasmettere il valore "time" a datetime. In altre parole, puoi fare: datetime + time
Sam

1
Le date di @dnolan nel server SQL NON sono memorizzate come float. Dove diavolo hai imparato questo? Sono memorizzati come numeri interi : la parte della data è il numero di giorni dalla data di ancoraggio e la parte del tempo è il numero di "tick" dalla mezzanotte, i tick sono definiti come 1/300 s per datetimee più preciso per timee datetime2.
ErikE,

129

Se l'elemento ora della colonna della data e l'elemento data della colonna dell'ora sono entrambi zero, la risposta di Lieven è ciò di cui hai bisogno. Se non puoi garantire che sarà sempre così, allora diventa leggermente più complicato:

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

Grazie per la risposta Luke. Fortunatamente, in questo caso posso garantire che gli altri articoli sono sempre zero, penso che i 2 campi possano anche essere 1 dall'altra parte il codice di terze parti che fa l'estrazione per noi.
Jon Winstanley,

6
Ho avuto lo stesso problema dell'OP, tranne che so che le parti non necessarie non sono mai zero. Questo è stato quindi incredibilmente utile, se potessi votarti due volte lo farei!

Questo mi ha salvato! Stavo convertendo entrambi in caratteri e poi concedendo e poi di nuovo in DATETIME, ma poi non sono riuscito a indicizzarlo, perché SQL ha detto che non era deterministico. Questo apparentemente è deterministico !!! GRAZIE !!! TU !!!
eidylon,

4
La tua versione di SQL Server 2008 non funziona. The data types datetime and time are incompatible in the add operator.
Martin Smith,

@Martin: ho rimosso la versione SQL2008 non funzionante.
Luca

26

Questa è una soluzione alternativa senza conversioni di caratteri:

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

Otterrai solo una precisione di millisecondi in questo modo, ma normalmente sarebbe OK. Ho provato questo in SQL Server 2008.


14

Questo ha funzionato per me

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

(su SQL 2008 R2)


1
Ha funzionato benissimo in SQL Server 2008.
Tobias,

7
Ottengo I tipi di dati datetime e time sono incompatibili nell'operatore add. errore su SQL Server 2012
Devin Prejean,

4
SQL 2012 I tipi di dati datetime e time sono incompatibili nell'operatore add
Raffaeu,

3
Questo non funziona più in SQL Server 2012 e versioni successive (interruzione delle modifiche). Vedi qui per i dettagli: social.msdn.microsoft.com/forums/azure/en-US/…
Heinzi

10

Se non si utilizza SQL Server 2008 (ovvero si dispone solo di un tipo di dati DateTime), è possibile utilizzare il seguente TSQL (dichiaratamente approssimativo e pronto) per ottenere ciò che si desidera:

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)

È grezzo e pronto, ma funziona!


9
  1. Se entrambi i campi sono datetime, semplicemente aggiungerli funzionerà.

    per esempio:

    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. Se hai utilizzato il tipo di dati Data e ora, basta trasmettere l'ora al datetime

    per esempio:

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

3

Convertire la prima data memorizzata in un campo datetime in una stringa, quindi convertire l'ora memorizzata in un campo datetime in una stringa, aggiungere i due e riconvertire nuovamente in un campo datetime utilizzando tutti i formati di conversione noti.

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

3
La conversione in stringa è più lenta di dateadd. stackoverflow.com/questions/2775/...
Erike

2

Ho avuto molti errori come sopra indicato, quindi l'ho fatto in questo modo

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

Ha funzionato per me.


2

Converti entrambi i campi in DATETIME:

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

e se stai usando Getdate()usa prima questo:

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

stampe:

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

Funziona come un fascino


0

SELEZIONA CAST (CAST (@DateField come data) Come DateTime) + CAST (CAST (@TimeField come ora) Come DateTime)


0

Un altro modo è quello di utilizzare CONCATe CAST, tenere presente, che è necessario utilizzare DATETIME2(x)per farlo funzionare. Puoi impostare xqualsiasi cosa tra 0-7 7significato senza perdita di precisione.

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

ritorna 2018-03-12 07:00:00.0000000

Testato su SQL Server 14


-1

Per combinare data da una colonna datetime e ora da un'altra colonna datetime questa è la soluzione più veloce per te:

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

Risultati in errore "I tipi di dati datetime e time sono incompatibili nell'operatore add."
Oskar Berggren,

-1

Mi sono imbattuto in una situazione simile in cui ho dovuto unire i campi Data e Ora nel campo DateTime. Nessuna delle soluzioni sopra menzionate funziona, specialmente aggiungendo due campi poiché il tipo di dati per l'aggiunta di questi 2 campi non è lo stesso.

Ho creato la soluzione seguente, in cui ho aggiunto ora e poi parte dei minuti alla data. Questo ha funzionato magnificamente per me. Si prega di controllare e fammi sapere se si verificano problemi.

; con tbl as (selezionare StatusTime = '12 / 30/1899 5:17:00 PM ', StatusDate =' 24/07/2019 12:00:00 AM ') selezionare DATEADD (MI, DATEPART (MINUTE, CAST (tbl .StatusTime AS TIME)), DATEADD (HH, DATEPART (HOUR, CAST (tbl.StatusTime AS TIME)), CAST (tbl.StatusDate as DATETIME))) da tbl

Risultato: 24-07-2019 17: 17: 00.000

Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.