Jak połączyć datę z jednego pola z czasem z innego pola - MS SQL Server

198

W wyciągu, z którym mam do czynienia, mam 2 datetimekolumny. Jedna kolumna przechowuje daty, a druga godziny, jak pokazano.

Jak mogę wysłać zapytanie do tabeli, aby połączyć te dwa pola w 1 kolumnę typu datetime?

Daktyle

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

Czasy

1899-12-30 12:30:00.000
1899-12-30 10:00:00.000
1899-12-30 10:00:00.000
Jon Winstanley
źródło

Odpowiedzi:

252

Możesz po prostu dodać dwa.

  • jeśliTime part swojej Datekolumnie jest zawsze zero
  • iDate part swojej Timekolumnie jest zawsze zero (data bazowa: 1 stycznia 1900)

Dodanie ich zwraca poprawny wynik.

SELECT Combined = MyDate + MyTime FROM MyTable

Uzasadnienie (uznanie dla ErikE / dnolan)

Działa to w ten sposób ze względu na sposób, w jaki data jest przechowywana jako dwa 4 bajty, Integersprzy czym lewe 4 bajty to datei prawe 4 bajty to time. To jak robienie$0001 0000 + $0000 0001 = $0001 0001

Edycja dotycząca nowych typów SQL Server 2008

Datei Timesą to typy wprowadzone w SQL Server 2008. Jeśli nalegasz na dodanie, możesz użyćCombined = CAST(MyDate AS DATETIME) + CAST(MyTime AS DATETIME)

Edycja2 dotycząca utraty precyzji w programie SQL Server 2008 i nowszych (podziękowania dla Martina Smitha)

Zobacz, jak połączyć datę i godzinę z datetime2 w SQL Server? aby zapobiec utracie precyzji przy użyciu SQL Server 2008 i nowszych wersji.

Lieven Keersmaekers
źródło
2
@Jon, to prawda, o ile element godziny w kolumnie daty i element daty w kolumnie czasu są równe zero.
Łukasza
1
Jesteś najprawdopodobniej doświadcza co kasowych opisano tutaj groups.google.be/group/... Borland * + autor% 3A teamb * 1ab62659d8be3135
Lieven Keersmaekers
2
Data „zero” w SQL Server to 1900-01-01: nie?
Andriy M
1
Kiedy próbowałem, nie musiałem rzutować wartości „time” na datetime. Innymi słowy, możesz zrobić: datetime + time
Sam
1
@dnolan daty na serwerze SQL NIE są przechowywane jako float. Gdzie, u licha, nauczyłeś się tego? Są one przechowywane jako liczby całkowite : część daty to liczba dni od daty zakotwiczenia, a część czasu to liczba „tyknięć” od północy, przy czym tiki są zdefiniowane jako 1/300 s dla, datetimea dokładniej dla timei datetime2.
ErikE
129

Jeśli element czasu w kolumnie daty i element daty w kolumnie czasu są równe zero , odpowiedź Lieven jest tym, czego potrzebujesz. Jeśli nie możesz zagwarantować, że tak będzie zawsze, będzie to nieco bardziej skomplikowane:

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
Łukasz
źródło
Dzięki za odpowiedź, Luke. Na szczęście w tym przypadku mogę zagwarantować, że inne elementy są zawsze równe zero, myślę, że 2 pola mogą nawet być 1 po drugiej stronie kodu innej firmy, który robi dla nas wyciąg.
Jon Winstanley
6
Miałem ten sam problem co OP, ale wiem, że niepotrzebne części nigdy nie są zerowe. Było to zatem niezmiernie przydatne, gdybym mógł dwukrotnie zagłosować!
To mnie uratowało! Konwertowałem zarówno znaki, jak i kończę, a potem wracam do DATETIME, ale potem nie mogłem tego zindeksować, ponieważ SQL powiedział, że jest niedeterministyczny. To pozornie JEST deterministyczne !!! DZIĘKUJEMY !!! TY !!!
eidylon
4
Twoja wersja SQL Server 2008 nie działa. The data types datetime and time are incompatible in the add operator.
Martin Smith
@ Martin: Usunąłem zepsutą wersję SQL2008.
Łukasza
26

Jest to alternatywne rozwiązanie bez konwersji znaków:

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

W ten sposób uzyskasz dokładność tylko w milisekundach, ale normalnie byłoby to OK. Przetestowałem to w SQL Server 2008.

Jojje
źródło
14

To zadziałało dla mnie

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

(w SQL 2008 R2)

biso
źródło
1
Świetnie sprawdził się w SQL Server 2008.
Tobias
7
Rozumiem Typy danych data i godzina są niezgodne w operatorze dodawania. błąd w SQL Server 2012
Devin Prejean
4
SQL 2012 Typy danych data i godzina są niezgodne w operatorze dodawania
Raffaeu
3
To już nie działa w SQL Server 2012 i nowszych wersjach (zmiana zerwania). Zobacz szczegóły: social.msdn.microsoft.com/forums/azure/en-US/…
Heinzi
10

Jeśli nie używasz SQL Server 2008 (tzn. Masz tylko typ danych DateTime), możesz użyć następującego (co prawda zgrubnego i gotowego) TSQL, aby osiągnąć to, co chcesz:

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)

Jest szorstki i gotowy, ale działa!

CraigTP
źródło
9
  1. Jeśli oba pola są datetime, wystarczy dodać te pola.

    na przykład:

    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. Jeśli użyłeś typu daty i godziny, po prostu rzutuj czas na datę i godzinę

    na przykład:

    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
źródło
3

Konwertuj pierwszą datę przechowywaną w polu daty i godziny na ciąg, a następnie przekonwertuj czas przechowywany w polu daty i godziny na ciąg, dołącz dwie i przekonwertuj z powrotem na pole daty i godziny za pomocą znanych formatów konwersji.

Convert(datetime, Convert(char(10), MYDATETIMEFIELD, 103) + ' ' + Convert(char(8), MYTIMEFIELD, 108), 103) 
SPE109
źródło
3
Konwersja na ciąg znaków jest wolniejsza niż dateadd. stackoverflow.com/questions/2775/…
ErikE
2

Miałem wiele błędów, jak wspomniano powyżej, więc zrobiłem to w ten sposób

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

To zadziałało dla mnie.

Tomek
źródło
2

Konwertuj oba pola na DATETIME:

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

a jeśli używasz, Getdate()użyj tego w pierwszej kolejności:

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

Wydruki:

2009-03-12 10:00:00.000
2009-03-26 10:00:00.000
2009-03-30 12:30:00.000
Konstantin Tarkus
źródło
1
SELECT CAST(your_date_column AS date) + CAST(your_time_column AS datetime) FROM your_table

Działa jak marzenie

Kristian Radolovic
źródło
0

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

Szach w persji
źródło
0

Innym sposobem jest użycie CONCATi CASTnależy pamiętać, że musisz go użyć, DATETIME2(x)aby działał. Możesz ustawić xdowolną wartość pomiędzy 0-7 7bez utraty precyzji.

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

Zwroty 2018-03-12 07:00:00.0000000

Testowane na SQL Server 14

LuckyLikey
źródło
-1

Aby połączyć datę z kolumny z datą i godziną z innej kolumny z datą, jest to najlepsze najszybsze rozwiązanie dla Ciebie:

select cast(cast(DateColumn as date) as datetime) + cast(TimeColumn as datetime) from YourTable
Wael Galal El Deen
źródło
Powoduje błąd „Typy danych data i czas są niezgodne w operatorze dodawania”.
Oskar Berggren,
-1

Zetknąłem się z podobną sytuacją, w której musiałem scalić pola daty i godziny z polem daty i godziny. Żadne z wyżej wymienionych rozwiązań nie działa, szczególnie dodanie dwóch pól jako typu danych dla dodania tych dwóch pól nie jest takie samo.

Stworzyłem poniższe rozwiązanie, w którym do daty dodałem godzinę, a następnie minutę. To działało dla mnie pięknie. Sprawdź to i daj mi znać, jeśli napotkasz jakiekolwiek problemy.

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

Wynik: 2019-07-24 17: 17: 00.000

Rahul Shinde
źródło