Comment combiner la date d'un champ avec l'heure d'un autre champ - MS SQL Server

198

Dans un extrait que je traite, j'ai 2 datetimecolonnes. Une colonne stocke les dates et une autre les heures comme indiqué.

Comment puis-je interroger la table pour combiner ces deux champs en 1 colonne de type datetime?

Rendez-vous

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

Fois

1899-12-30 12:30:00.000
1899-12-30 10:00:00.000
1899-12-30 10:00:00.000
Jon Winstanley
la source

Réponses:

253

Vous pouvez simplement ajouter les deux.

  • si le Time partde votre Datecolonne est toujours nul
  • et le Date partde votre Timecolonne est également toujours nul (date de base: 1er janvier 1900)

Leur ajout renvoie le résultat correct.

SELECT Combined = MyDate + MyTime FROM MyTable

Justification (bravo à ErikE / dnolan)

Cela fonctionne comme cela en raison de la façon dont la date est stockée sur deux octets, Integersles 4 octets gauches étant les date4 octets droits étant les time. C'est comme faire$0001 0000 + $0000 0001 = $0001 0001

Modifier concernant les nouveaux types SQL Server 2008

Dateet Timesont des types introduits dans SQL Server 2008. Si vous insistez pour ajouter, vous pouvez utiliserCombined = CAST(MyDate AS DATETIME) + CAST(MyTime AS DATETIME)

Edit2 concernant la perte de précision dans SQL Server 2008 et versions ultérieures (bravo à Martin Smith)

Jetez un œil à Comment combiner la date et l'heure à datetime2 dans SQL Server? pour éviter toute perte de précision à l'aide de SQL Server 2008 et versions ultérieures.

Lieven Keersmaekers
la source
2
@Jon, c'est vrai tant que l'élément de temps de la colonne de date et l'élément de date de la colonne de temps sont tous les deux nuls.
LukeH
1
Vous rencontrez très probablement ce qui est décrit ici groups.google.be/group/… borland * + author% 3A teamb * # 1ab62659d8be3135
Lieven Keersmaekers
2
La date "zéro" dans SQL Server est 1900-01-01, non?
Andriy M
1
Lorsque j'ai essayé cela, je n'ai pas eu besoin de convertir la valeur «time» en datetime. En d'autres termes, vous pouvez faire: datetime + time
Sam
1
Les dates @dnolan dans le serveur SQL ne sont PAS stockées en tant que float. Où diable avez-vous appris cela? Ils sont stockés sous forme d' entiers : la partie date est le nombre de jours depuis une date d'ancrage, et la partie heure est le nombre de "ticks" depuis minuit, les ticks étant définis comme 1/300 s pour datetimeet plus précis pour timeet datetime2.
ErikE
129

Si l'élément de temps de votre colonne de date et l'élément de date de votre colonne de temps sont tous deux nuls, alors la réponse de Lieven est ce dont vous avez besoin. Si vous ne pouvez pas garantir que ce sera toujours le cas, cela devient un peu plus compliqué:

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
la source
Merci pour la réponse Luke. Heureusement, dans ce cas, je peux garantir que les autres éléments sont toujours nuls, je pense que les 2 champs peuvent même être 1 de l'autre côté du code tiers qui fait l'extrait pour nous.
Jon Winstanley
6
J'ai eu le même problème que l'OP sauf que je sais que les pièces inutiles ne sont jamais nulles. Cela a donc été extrêmement utile, si je pouvais vous voter deux fois, je le ferais!
Cela m'a sauvé! Je convertissais les deux en caractères, puis concédais, puis revenais à DATETIME, mais je ne pouvais pas l'indexer, car SQL a dit qu'il n'était pas déterministe. C'est apparemment déterministe !!! MERCI !!! TOI !!!
eidylon
4
Votre version de SQL Server 2008 ne fonctionne pas. The data types datetime and time are incompatible in the add operator.
Martin Smith
@Martin: J'ai supprimé la version cassée de SQL2008.
LukeH
26

Il s'agit d'une solution alternative sans aucune conversion de caractères:

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

Vous n'obtiendrez que des millisecondes de cette façon, mais ce serait normalement OK. J'ai testé cela dans SQL Server 2008.

Jojje
la source
14

Cela a fonctionné pour moi

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

(sur SQL 2008 R2)

biso
la source
1
Fonctionne très bien dans SQL Server 2008.
Tobias
7
J'obtiens Les types de données datetime et time sont incompatibles dans l'opérateur d'ajout. erreur sur SQL Server 2012
Devin Prejean
4
SQL 2012 Les types de données datetime et time sont incompatibles dans l'opérateur add
Raffaeu
3
Cela ne fonctionne plus dans SQL Server 2012 et supérieur (rupture du changement). Voir ici pour plus de détails: social.msdn.microsoft.com/forums/azure/en-US/…
Heinzi
10

Si vous n'utilisez pas SQL Server 2008 (c'est-à-dire que vous ne disposez que d'un type de données DateTime), vous pouvez utiliser le TSQL suivant (certes approximatif et prêt) pour obtenir ce que vous voulez:

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)

C'est rude et prêt, mais ça marche!

CraigTP
la source
9
  1. Si vos deux champs sont datetime, il suffit de les ajouter.

    par exemple:

    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 vous avez utilisé le type de données Date et heure, convertissez simplement l'heure en date et heure

    par exemple:

    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
la source
3

Convertissez la première date stockée dans un champ datetime en chaîne, puis convertissez l'heure stockée dans un champ datetime en chaîne, ajoutez les deux et reconvertissez en champ datetime en utilisant tous les formats de conversion connus.

Convert(datetime, Convert(char(10), MYDATETIMEFIELD, 103) + ' ' + Convert(char(8), MYTIMEFIELD, 108), 103) 
SPE109
la source
3
La conversion en chaîne est plus lente que dateadd. stackoverflow.com/questions/2775/…
ErikE
2

J'ai eu beaucoup d'erreurs comme indiqué ci-dessus, donc je l'ai fait comme ça

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

Ça a marché pour moi.

À M
la source
2

Convertissez les deux champs en DATETIME:

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

et si vous utilisez, Getdate()utilisez d'abord:

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

Tirages:

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

Fonctionne comme un charme

Kristian Radolovic
la source
0

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

Shah
la source
0

Une autre façon consiste à utiliser CONCATet CAST, soyez conscient, que vous devez utiliser DATETIME2(x)pour le faire fonctionner. Vous pouvez définir xn'importe quoi entre ce qui 0-7 7signifie aucune perte de précision.

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

Retour 2018-03-12 07:00:00.0000000

Testé sur SQL Server 14

LuckyLikey
la source
-1

Pour combiner la date d'une colonne datetime et l'heure d'une autre colonne datetime, c'est la meilleure solution la plus rapide pour vous:

select cast(cast(DateColumn as date) as datetime) + cast(TimeColumn as datetime) from YourTable
Wael Galal El Deen
la source
Résultats en erreur "Les types de données datetime et time sont incompatibles dans l'opérateur d'ajout."
Oskar Berggren
-1

J'ai rencontré une situation similaire où j'ai dû fusionner les champs Date et Heure avec le champ DateTime. Aucune des solutions mentionnées ci-dessus ne fonctionne, en particulier l'ajout de deux champs car le type de données pour l'ajout de ces 2 champs n'est pas le même.

J'ai créé la solution ci-dessous, où j'ai ajouté une partie heure puis minute à la date. Cela a très bien fonctionné pour moi. Veuillez le vérifier et faites-moi savoir si vous rencontrez des problèmes.

; avec tbl as (sélectionnez StatusTime = '12 / 30/1899 5:17:00 PM ', StatusDate =' 7/24/2019 12:00:00 AM ') sélectionnez DATEADD (MI, DATEPART (MINUTE, CAST (tbl .StatusTime AS TIME)), DATEADD (HH, DATEPART (HOUR, CAST (tbl.StatusTime AS TIME)), CAST (tbl.StatusDate as DATETIME))) from tbl

Résultat: 2019-07-24 17: 17: 00.000

rahul shinde
la source