Cómo combinar la fecha de un campo con la hora de otro campo - MS SQL Server

198

En un extracto que estoy tratando, tengo 2 datetimecolumnas. Una columna almacena las fechas y otra las horas como se muestra.

¿Cómo puedo consultar la tabla para combinar estos dos campos en 1 columna de tipo datetime?

fechas

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

Veces

1899-12-30 12:30:00.000
1899-12-30 10:00:00.000
1899-12-30 10:00:00.000
Jon Winstanley
fuente

Respuestas:

253

Simplemente puede agregar los dos.

  • si el Time partde tu Datecolumna es siempre cero
  • y el Date partde su Timecolumna también es siempre cero (fecha base: 1 de enero de 1900)

Agregarlos devuelve el resultado correcto.

SELECT Combined = MyDate + MyTime FROM MyTable

Justificación (felicitaciones a ErikE / dnolan)

Funciona así debido a la forma en que la fecha se almacena como dos de 4 bytes, Integerssiendo los 4 bytes de la izquierda los 4 bytes de datela derecha time. Es como hacer$0001 0000 + $0000 0001 = $0001 0001

Editar con respecto a los nuevos tipos de SQL Server 2008

Datey Timeson tipos introducidos en SQL Server 2008. Si insiste en agregar, puede usarCombined = CAST(MyDate AS DATETIME) + CAST(MyTime AS DATETIME)

Edit2 con respecto a la pérdida de precisión en SQL Server 2008 y versiones posteriores (felicitaciones a Martin Smith)

Eche un vistazo a ¿Cómo combinar fecha y hora para datetime2 en SQL Server? para evitar la pérdida de precisión con SQL Server 2008 y versiones posteriores.

Lieven Keersmaekers
fuente
2
@ Jon, es cierto siempre que el elemento de tiempo de la columna de fecha y el elemento de fecha de la columna de tiempo sean ambos cero.
LukeH
1
Lo más probable es que experimente lo que se describe aquí groups.google.be/group/… borland * + author% 3A teamb * # 1ab62659d8be3135
Lieven Keersmaekers
2
La fecha "cero" en SQL Server es 1900-01-01, ¿no?
Andriy M
1
Cuando intenté esto, no necesitaba convertir el valor de 'hora' en datetime. En otras palabras, puedes hacer: datetime + time
Sam
1
Las fechas de @dnolan en el servidor SQL NO se almacenan como float. ¿Dónde diablos aprendiste esto? Se almacenan como enteros : la parte de la fecha es el número de días desde una fecha de anclaje, y la parte de la hora es el número de "ticks" desde la medianoche, definiéndose los ticks como 1/300 s para datetimey más precisos para timey datetime2.
ErikE
129

Si el elemento de tiempo de su columna de fecha y el elemento de fecha de su columna de tiempo son ambos cero, entonces la respuesta de Lieven es lo que necesita. Si no puede garantizar que ese sea siempre el caso, entonces se vuelve un poco más complicado:

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
LukeH
fuente
Gracias por la respuesta Luke. Afortunadamente, en este caso puedo garantizar que otros elementos son siempre cero, creo que los 2 campos pueden ser incluso 1 en el otro lado del código de terceros que hace el extracto por nosotros.
Jon Winstanley
66
Tuve el mismo problema que el OP, excepto que sé que las partes innecesarias nunca son cero. Por lo tanto, esto ha sido inmensamente útil, ¡si pudiera votarlo dos veces lo haría!
Esto me salvó! Estaba convirtiendo ambos en caracteres y luego concatenando y luego nuevamente a DATETIME, pero luego no pude indexarlo, porque SQL dijo que no era determinista. ¡Esto aparentemente ES determinista! GRACIAS !!! TÚ !!!
Eidylon
44
Su versión de SQL Server 2008 no funciona. The data types datetime and time are incompatible in the add operator.
Martin Smith
@ Martin: eliminé la versión rota de SQL2008.
LukeH
26

Esta es una solución alternativa sin conversiones de caracteres:

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

De esta forma solo obtendrá una precisión de milisegundos, pero eso normalmente estaría bien. He probado esto en SQL Server 2008.

Jojje
fuente
14

Esto funciono para mi

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

(en SQL 2008 R2)

biso
fuente
1
Funcionó muy bien en SQL Server 2008.
Tobias
77
Obtengo Los tipos de datos datetime y time son incompatibles en el operador add. error en SQL Server 2012
Devin Prejean
44
SQL 2012 Los tipos de datos datetime y time son incompatibles en el operador add
Raffaeu
3
Esto ya no funciona en SQL Server 2012 y versiones posteriores (cambio de ruptura). Ver aquí para más detalles: social.msdn.microsoft.com/forums/azure/en-US/…
Heinzi
10

Si no está usando SQL Server 2008 (es decir, solo tiene un tipo de datos DateTime), puede usar el siguiente TSQL (ciertamente tosco y listo) para lograr lo que desea:

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 duro y listo, pero funciona!

CraigTP
fuente
9
  1. Si ambos campos son de fecha y hora, simplemente agregarlos funcionará.

    p.ej:

    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. Si utilizó el tipo de datos Fecha y hora, simplemente transmita la hora a fecha y hora

    p.ej:

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

Convierta la primera fecha almacenada en un campo de fecha y hora en una cadena, luego convierta la hora almacenada en un campo de fecha y hora en una cadena, agregue las dos y vuelva a convertir en un campo de fecha y hora, todo utilizando formatos de conversión conocidos.

Convert(datetime, Convert(char(10), MYDATETIMEFIELD, 103) + ' ' + Convert(char(8), MYTIMEFIELD, 108), 103) 
SPE109
fuente
3
La conversión a cadena es más lenta que dateadd. stackoverflow.com/questions/2775/…
ErikE
2

Tuve muchos errores como se indicó anteriormente, así que lo hice así

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

Funcionó para mi.

Tom
fuente
2

Convierta ambos campos en DATETIME:

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

y si estás usando Getdate()usa esto primero:

DECLARE @FechaActual DATETIME = CONVERT(DATE, GETDATE());
SELECT CAST(@FechaActual as DATETIME) + CAST(@HoraInicioTurno AS DATETIME)
Alex Briones
fuente
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

Huellas dactilares:

2009-03-12 10:00:00.000
2009-03-26 10:00:00.000
2009-03-30 12:30:00.000
Konstantin Tarkus
fuente
1
SELECT CAST(your_date_column AS date) + CAST(your_time_column AS datetime) FROM your_table

Funciona de maravilla

Kristian Radolovic
fuente
0

SELECT CAST (CAST (@DateField As Date) As DateTime) + CAST (CAST (@TimeField As Time) As DateTime)

Cha
fuente
0

Otra forma es usar CONCATy CAST, tenga en cuenta, que necesita usar DATETIME2(x)para que funcione. Puede establecer xcualquier cosa entre lo que 0-7 7significa que no hay pérdida de precisión.

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

Devoluciones 2018-03-12 07:00:00.0000000

Probado en SQL Server 14

LuckyLikey
fuente
-1

Para combinar la fecha de una columna datetime y la hora de otra columna datetime, esta es la mejor solución más rápida para usted:

select cast(cast(DateColumn as date) as datetime) + cast(TimeColumn as datetime) from YourTable
Wael Galal El Deen
fuente
Resultados en el error "Los tipos de datos datetime y time son incompatibles en el operador add".
Oskar Berggren
-1

Me encontré con una situación similar en la que tuve que fusionar los campos Fecha y Hora con el campo Fecha y hora. Ninguna de las soluciones mencionadas anteriormente funciona, especialmente agregar dos campos como el tipo de datos para agregar estos 2 campos no es lo mismo.

Creé la siguiente solución, donde agregué horas y luego minutos a la fecha. Esto funcionó muy bien para mí. Compruébalo y avísame si tienes algún problema.

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

Resultado: 2019-07-24 17: 17: 00.000

Rahul Shinde
fuente