2013-09-04 22 views
16

Utilizzo di SQL Server 2008, questa query grandi opere:Combinando (concatenare) data e ora in un datetime

select CAST(CollectionDate as DATE), CAST(CollectionTime as TIME) 
from field 

mi dà due colonne come questo:

2013-01-25 18:53:00.0000000 
2013-01-25 18:53:00.0000000 
2013-01-25 18:53:00.0000000 
2013-01-25 18:53:00.0000000 
    . 
    . 
    . 

che sto cercando di coniugare li in un unico datetime con il segno più, in questo modo:

select CAST(CollectionDate as DATE) + CAST(CollectionTime as TIME) 
from field 

ho guardato su una decina di siti web, tra cui risposte o n questo sito (come this one), e tutti sembrano concordare sul fatto che il segno più dovrebbe funzionare, ma ho l'errore:

Msg 8117, Level 16, State 1, Line 1
Operand data type date is invalid for add operator.

Tutti i campi sono non-zero e non nullo. Ho anche provato la funzione CONVERT e ho provato a trasmettere questi risultati come varchar, lo stesso problema. Questo non può essere così difficile come lo sto facendo.

Qualcuno può dirmi perché questo non funziona? Grazie per qualsiasi aiuto.

+1

Quali sono i tipi di dati originali per ogni colonna ?, e se sono stringhe, come vengono i dati memorizzati lì? (AAAA-MM-GG, AAAAMMGG, ecc.) – Lamak

+0

In realtà, domanda di follow-up a te e @ Aaron Bertrand, se sto CASTING (o CONVERTING) i miei dati nella query stessa, è importante se i dati sottostanti sono memorizzati come stringhe o date? Sto archiviando come campi datetime, ma solo curioso. – Stanton

+0

@Stanton certo, importa. Perché passare attraverso due livelli di cast/convert quando potresti non averne bisogno? –

risposta

30

Supponendo che i tipi di dati sottostanti sono data/ora/datetime, ecc

SELECT CONVERT(DATETIME, CONVERT(CHAR(8), CollectionDate, 112) 
    + ' ' + CONVERT(CHAR(8), CollectionTime, 108)) 
    FROM dbo.whatever; 

Se non lo sono, WHY NOT, e per ottenere una risposta significativa, devi dirci che tipi sono e in che formato sono archiviati i dati. O semplicemente aggiusta la tabella.

+0

Aaron, grazie per la vostra risposta, e comprensione della mia domanda di follow-up di cui sopra sarebbe apprezzato. – Stanton

+0

Funziona per sql-server-2012. Nice Job – FirebladeDan

-4

Usa Concat il MySQL ha questa funzione

+0

Ma questo è per SQL Server – Lamak

+0

Provato che, non funziona con MS SQL 2008. – Stanton

+0

Non lo farebbe. concat è una funzione di stringa. – Amy

7

gettarlo ai datetime invece:

select CAST(CollectionDate as DATETIME) + CAST(CollectionTime as TIME) 
from field 

Questo funziona su SQL Server 2008 R2.

Se per qualche motivo si desidera assicurarsi che la prima parte non abbia un componente orario, prima lanciare il campo fino alla data, quindi tornare a datetime.

+2

'Msg 402, Level 16, State 1, Line 1 - I tipi di dati datetime e time non sono compatibili con l'operatore add.' –

+0

Bullseye! Grazie mille! – Stanton

+0

@AaronBertrand, quale versione di SQL Server stai usando? – Amy

1
DECLARE @ADate Date, @ATime Time, @ADateTime Datetime 

SELECT @ADate = '2010-02-20', @ATime = '18:53:00.0000000' 

SET @ADateTime = CAST (
    CONVERT(Varchar(10), @ADate, 112) + ' ' + 
    CONVERT(Varchar(8), @ATime) AS DateTime) 

SELECT @ADateTime [A nice datetime :)] 

Questo ti renderà un risultato valido.

0
drop table test 

create table test(
    CollectionDate date NULL, 
    CollectionTime [time](0) NULL, 
    CollectionDateTime as (isnull(convert(datetime,CollectionDate)+convert(datetime,CollectionTime),CollectionDate)) 
-- if CollectionDate is datetime no need to convert it above 
) 

insert test (CollectionDate, CollectionTime) 
values ('2013-12-10', '22:51:19.227'), 
     ('2013-12-10', null), 
     (null, '22:51:19.227') 

select * from test 

CollectionDate CollectionTime CollectionDateTime 
2013-12-10  22:51:19  2013-12-10 22:51:19.000 
2013-12-10  NULL   2013-12-10 00:00:00.000 
NULL   22:51:19  NULL 
0

Questo funziona in SQL 2008 e il 2012 per la produzione di datetime2:

declare @date date = current_timestamp; 
declare @time time = current_timestamp; 

select 
@date as date 
,@time as time 
,cast(@date as datetime) + cast(@time as datetime) as datetime 
,cast(@time as datetime2) as timeAsDateTime2 
,dateadd(dayofyear,datepart(dayofyear,@date) - 1,dateadd(year,datepart(year,@date) - 1900,cast(@time as datetime2))) as datetime2; 
-1
SELECT CONVERT(DATETIME, CONVERT(CHAR(8), date, 112) + ' ' + CONVERT(CHAR(8), time, 108)) 
    FROM tablename 
5

una soluzione più semplice (testato su SQL Server 2014 SP1 CU6)

Codice:

DECLARE @Date date = SYSDATETIME(); 

DECLARE @Time time(0) = SYSDATETIME(); 

SELECT CAST(CONCAT(@Date, ' ', @Time) AS datetime2(0)); 

Ciò funzionerebbe anche dato un tavolo con una sp data ecologica e un campo temporale specifico. Uso spesso questo metodo dato che disponiamo di dati del fornitore che utilizzano data e ora in due campi separati.

3

La soluzione semplice

SELECT CAST(CollectionDate as DATETIME) + CAST(CollectionTime as DATETIME) 
FROM field