Como combinar a data de um campo com a hora de outro campo - MS SQL Server

198

Em um extrato com o qual estou lidando, tenho 2 datetimecolunas. Uma coluna armazena as datas e outra as horas, conforme mostrado.

Como posso consultar a tabela para combinar esses dois campos em uma coluna do tipo datetime?

datas

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

Vezes

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

Respostas:

253

Você pode simplesmente adicionar os dois.

  • se o Time partda sua Datecoluna é sempre zero
  • e o Date partda sua Timecoluna também é sempre zero (data base: 1º de janeiro de 1900)

Adicioná-los retorna o resultado correto.

SELECT Combined = MyDate + MyTime FROM MyTable

Justificativa (parabéns a ErikE / dnolan)

Funciona assim devido à maneira como a data é armazenada como dois bytes de Integers4, sendo os 4 bytes esquerdos os datee os 4 bytes direitos os time. É como fazer$0001 0000 + $0000 0001 = $0001 0001

Editar sobre novos tipos do SQL Server 2008

Datee Timesão tipos introduzidos em SQL Server 2008. Se você insistir em adicionar, poderá usarCombined = CAST(MyDate AS DATETIME) + CAST(MyTime AS DATETIME)

Edit2 sobre perda de precisão no SQL Server 2008 e posterior (parabéns a Martin Smith)

Dê uma olhada em Como combinar data e hora com datetime2 no SQL Server? para evitar perda de precisão usando o SQL Server 2008 e superior.

Lieven Keersmaekers
fonte
2
@ Jon, é verdade, desde que o elemento time da coluna date e o elemento date da coluna time sejam zero.
31410 LukeH
1
Você está provavelmente experimentando o que é desribed aqui groups.google.be/group/... Borland * + autor% 3A teamb * # 1ab62659d8be3135
Lieven Keersmaekers
2
A data "zero" no SQL Server é 1900-01-01, não?
precisa
1
Quando tentei isso, não precisei converter o valor 'time' para datetime. Em outras palavras você pode fazer: datetime tempo +
Sam
1
As datas @dnolan no SQL server NÃO são armazenadas como float. Onde diabos você aprendeu isso? Eles são armazenados como números inteiros : a parte da data é o número de dias desde a data âncora e a parte da hora é o número de "ticks" desde a meia-noite, sendo os ticks definidos como 1/300 s datetimee mais precisos para timee datetime2.
ErikE
129

Se o elemento de tempo da sua coluna de data e o elemento de data da sua coluna de tempo forem zero, então a resposta de Lieven é o que você precisa. Se você não pode garantir que sempre será esse o caso, torna-se um pouco mais 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
fonte
Obrigado pela resposta Luke. Felizmente, neste caso, posso garantir que outros itens sejam sempre zero, acho que os 2 campos podem até ser 1 do outro lado do código de terceiros que extrai para nós.
31909 Jon Winstanley
6
Eu tive o mesmo problema que o OP, exceto que eu sei que as partes desnecessárias nunca são zero. Isso tem sido imensuravelmente útil, se eu pudesse votar duas vezes em você!
Isso me salvou! Eu estava convertendo ambos para chars e, em seguida, concedia e voltava para DATETIME, mas não podia indexá-lo, porque o SQL dizia que não era determinístico. Isso aparentemente é determinístico !!! OBRIGADO !!! VOCÊS !!!
eidylon
4
Sua versão do SQL Server 2008 não funciona. The data types datetime and time are incompatible in the add operator.
Martin Smith
@ Martin: Eu removi a versão quebrada do SQL2008.
LukeH
26

Esta é uma solução alternativa sem nenhuma conversão de caracteres:

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

Você só terá precisão de milissegundos dessa maneira, mas isso normalmente seria bom. Eu testei isso no SQL Server 2008.

Jojje
fonte
14

Isso funcionou para mim

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

(no SQL 2008 R2)

biso
fonte
1
Funcionou muito bem no SQL Server 2008.
Tobias
7
Recebo Os tipos de dados datetime e time são incompatíveis no operador add. erro no SQL Server 2012
Devin Prejean
4
SQL 2012 Os tipos de dados datetime e time são incompatíveis no operador add
Raffaeu
3
Isso não funciona mais no SQL Server 2012 e acima (quebra de mudança). Veja aqui para detalhes: social.msdn.microsoft.com/forums/azure/en-US/…
Heinzi
10

Se você não estiver usando o SQL Server 2008 (ou seja, você possui apenas um tipo de dados DateTime), poderá usar o seguinte TSQL (reconhecidamente bruto e pronto) para obter o que deseja:

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)

É áspero e pronto, mas funciona!

CraigTP
fonte
9
  1. Se os dois campos tiverem data e hora, basta adicioná-los.

    por exemplo:

    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 você usou o tipo de dados Data e hora, basta converter o horário para data e hora

    por exemplo:

    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
fonte
3

Converta a primeira data armazenada em um campo de data e hora em uma sequência de caracteres, depois converta a hora armazenada em um campo de data e hora em sequência, acrescente as duas e converta novamente em um campo de data e hora, usando todos os formatos de conversão conhecidos.

Convert(datetime, Convert(char(10), MYDATETIMEFIELD, 103) + ' ' + Convert(char(8), MYTIMEFIELD, 108), 103) 
SPE109
fonte
3
A conversão em string é mais lenta que o dateadd. stackoverflow.com/questions/2775/…
ErikE
2

Eu tive muitos erros, como indicado acima, então eu fiz assim

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

Funcionou para mim.

Tom
fonte
2

Converta os dois campos em DATETIME:

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

e se você estiver usando, Getdate()use isso primeiro:

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

Impressões:

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

Funciona como um encanto

Kristian Radolovic
fonte
0

SELECT CAST (CAST (@DateField Como Data) Como DateTime) + CAST (CAST (@TimeField Como Hora) Como DateTime)


fonte
0

Outra maneira é usar CONCATe CASTestar ciente de que você precisa usá DATETIME2(x)-lo para fazê-lo funcionar. Você pode definir xqualquer coisa entre 0-7 7significando nenhuma perda de precisão.

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

Devoluções 2018-03-12 07:00:00.0000000

Testado no SQL Server 14

LuckyLikey
fonte
-1

Para combinar data de uma coluna de data e hora e hora de outra coluna de data e hora, esta é a melhor solução mais rápida para você:

select cast(cast(DateColumn as date) as datetime) + cast(TimeColumn as datetime) from YourTable
Wael Galal El Deen
fonte
Resultados no erro "Os tipos de dados datetime e time são incompatíveis no operador add".
Oskar Berggren
-1

Encontrei uma situação semelhante em que tive que mesclar os campos Data e Hora com o campo DateTime. Nenhuma das soluções mencionadas acima funciona, especialmente a adição de dois campos como o tipo de dados para adição desses 2 campos não é o mesmo.

Criei abaixo a solução, onde adicionei parte de hora e minuto para a data. Isso funcionou lindamente para mim. Verifique e avise-me se você tiver algum problema.

; com tbl como (selecione StatusTime = '12 / 30/1899 17:17:00 ', StatusDate =' 24/7/2019 12:00:00 ') selecione 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
fonte