web-dev-qa-db-fra.com

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

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

Comment interroger la table pour combiner ces deux champs en une 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

Horaires

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

Vous pouvez simplement ajouter les deux.

  • if le Time part de votre colonne Date est toujours zéro 
  • et le Date part de votre colonne Time est également toujours égal à zéro (date de base: le 1er janvier 1900)

Les ajouter renvoie le résultat correct.

SELECT Combined = MyDate + MyTime FROM MyTable

Justification (félicitations à ErikE/dnolan)

It works like this due to the way the date is stored as two 4-byte `Integers` with the
left 4-bytes being the `date` and the right 4-bytes being the `time`.  

Its like doing $0001 0000 + $0000 0001 = $0001 0001

Modifier concernant les nouveaux types SQL Server 2008

Date et Time sont des types introduits dans SQL Server 2008. Si vous insistez pour ajouter, vous pouvez utiliser Combined = CAST(MyDate AS DATETIME) + CAST(MyTime AS DATETIME)

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

Regardez Comment combiner la date et l'heure à datetime2 dans SQL Server? pour éviter toute perte de précision lors de l'utilisation de SQL Server 2008 et versions ultérieures.

233

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 Réponse de Lieven est ce dont vous avez besoin. Si vous ne pouvez pas garantir que ce sera toujours le cas, cela deviendra 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
125
LukeH

Ceci est une solution alternative sans conversion de caractères:

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

Vous obtiendrez une précision de quelques millisecondes de cette façon, mais normalement, ce serait OK. J'ai testé cela dans SQL Server 2008.

21
Jojje

Cela a fonctionné pour moi

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

(sur SQL 2008 R2)

11
biso
  1. Si vos deux champs sont datetime, il vous 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 & Time, il vous suffit de convertir l'heure en datetime 

    par exemple:

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

Si vous n’utilisez pas SQL Server 2008 (c’est-à-dire que vous n’avez qu’un type de données DateTime), vous pouvez utiliser le TSQL (certes approximatif) suivant 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 dur et prêt, mais ça marche!

9
CraigTP

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-la en champ datetime en utilisant tous les formats de conversion connus.

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

Convertissez les deux champs en DATETIME: 

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

et si vous utilisez Getdate() utilisez ceci en premier:

DECLARE @FechaActual DATETIME = CONVERT(DATE, GETDATE());
SELECT CAST(@FechaActual as DATETIME) + CAST(@HoraInicioTurno AS DATETIME)
1
Alex Briones
SELECT CAST(your_date_column AS date) + CAST(your_time_column AS datetime) FROM your_table

Fonctionne comme un charme

1
Kristian Radolovic
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

Impressions:

2009-03-12 10:00:00.000
2009-03-26 10:00:00.000
2009-03-30 12:30:00.000
1
Konstantin Tarkus

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

Cela a fonctionné pour moi.

1
Tom

Une autre méthode consiste à utiliser CONCATet CAST. Sachez que vous devez utiliser DATETIME2(x) pour que cela fonctionne. Vous pouvez définir x sur n'importe quoi entre 0-77, ce qui signifie qu'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))

Retourne 2018-03-12 07:00:00.0000000

Testé sur SQL Server 14

0
LuckyLikey